(反)序列化流

简介: (反)序列化流

序列化是将对象转换为字节序列的过程,以便在网络上传输或持久化到存储介质中。而序列化流(ObjectInputStream 和 ObjectOutputStream)是 Java 中用于进行对象序列化和反序列化的工具类。

在 Java 中,主要使用 java.io.ObjectInputStreamjava.io.ObjectOutputStream 类来实现序列化流的功能。

  1. ObjectOutputStream 用于将对象序列化为字节流。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
try (FileOutputStream fileOut = new FileOutputStream("object.ser");
     ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
    MyClass obj = new MyClass();
    out.writeObject(obj);
    // 对象已成功序列化为字节流
} catch (IOException e) {
    e.printStackTrace();
}
  1. 在上述示例中,创建了一个 ObjectOutputStream 对象,并传入一个底层的 FileOutputStream 作为字节输出流。然后,通过 writeObject 方法将一个对象(MyClass 类的实例)写入到输出流中,从而将其序列化为字节流。
  2. ObjectInputStream 用于将字节流反序列化为对象。
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
try (FileInputStream fileIn = new FileInputStream("object.ser");
     ObjectInputStream in = new ObjectInputStream(fileIn)) {
    MyClass obj = (MyClass) in.readObject();
    // 字节流已成功反序列化为对象
} catch (IOException | ClassNotFoundException e) {
    e.printStackTrace();
}
  1. 在上述示例中,创建了一个 ObjectInputStream 对象,并传入一个底层的 FileInputStream 作为字节输入流。然后,通过 readObject 方法从输入流中读取字节,并将其反序列化为对象(此处假设被读取的字节流确实表示一个 MyClass 对象)。

当涉及到序列化流的细节时,有一些重要的方面需要注意:

  1. 实现 Serializable 接口:要使一个对象可以被序列化,它的类必须实现 java.io.Serializable 接口。这是一个标记接口,没有定义任何方法。通过实现该接口,编译器将知道该类可以被序列化,并且可以将其对象转换为字节流。
  2. 序列化和反序列化的字段匹配:在进行序列化和反序列化时,对象的字段(即实例变量)将被写入和读取。确保被序列化和反序列化的对象具有相同的字段和字段顺序非常重要。如果序列化和反序列化的对象之间的字段不匹配,可能会导致数据损坏或异常。
  3. 版本控制:当序列化的类发生更改时,例如添加、删除或修改字段,建议为该类提供一个固定的版本号(serialVersionUID)。这样做可以在反序列化过程中提供版本控制,避免出现意外的问题。要自定义版本号,可以在类中添加以下代码:
private static final long serialVersionUID = 123456789L;
  1. 序列化多个对象:可以将多个对象连续地写入序列化流,然后再按照相同的顺序连续地从反序列化流中读取。这样可以将整个对象图保存到一个文件中,或者在网络上一次性传输多个对象。
  2. 序列化的限制:某些对象可能无法序列化。例如,如果对象中包含不可序列化的字段(如线程、文件句柄等),则会导致序列化失败。在这种情况下,可以通过将字段标记为 transient 来排除它们,使其不参与序列化过程。
  3. 序列化流的关闭:使用序列化流时,应该始终使用 try-with-resources 或手动关闭资源。序列化流中的缓冲区在关闭时会自动刷新并将剩余的数据写入到输出流中。

 

实例:

假设有一个学生类,用序列流写出一个学生

import java.io.Serializable;
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;
    private String studentId;
    public Student(String name, int age, String studentId) {
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }
    // 省略了getter和setter方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", studentId='" + studentId + '\'' +
                '}';
    }
}

接下来,我们将使用序列化流将一个学生对象写出到文件中。

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Main {
    public static void main(String[] args) {
        Student student = new Student("张三", 20, "20210001");
        try (FileOutputStream fileOut = new FileOutputStream("student.ser");
             ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
            out.writeObject(student);
            System.out.println("学生对象已成功写出到文件");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

以下是使用序列化流将学生对象写入idea的代码:

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Main {
    public static void main(String[] args) {
        try (FileInputStream fileIn = new FileInputStream("student.ser");
             ObjectInputStream in = new ObjectInputStream(fileIn)) {
            Student student = (Student) in.readObject();
            System.out.println(student);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}


相关文章
|
1天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
11天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
448 192
|
3天前
|
数据采集 消息中间件 人工智能
跨系统数据搬运的全方位解析,包括定义、痛点、技术、方法及智能体解决方案
跨系统数据搬运打通企业数据孤岛,实现CRM、ERP等系统高效互通。伴随数字化转型,全球市场规模超150亿美元,中国年增速达30%。本文详解其定义、痛点、技术原理、主流方法及智能体新范式,结合实在Agent等案例,揭示从数据割裂到智能流通的实践路径,助力企业降本增效,释放数据价值。
|
9天前
|
人工智能 自然语言处理 安全
国内主流Agent工具功能全维度对比:从技术内核到场景落地,一篇读懂所有选择
2024年全球AI Agent市场规模达52.9亿美元,预计2030年将增长至471亿美元,亚太地区增速领先。国内Agent工具呈现“百花齐放”格局,涵盖政务、金融、电商等多场景。本文深入解析实在智能实在Agent等主流产品,在技术架构、任务规划、多模态交互、工具集成等方面进行全维度对比,结合市场反馈与行业趋势,为企业及个人用户提供科学选型指南,助力高效落地AI智能体应用。
|
5天前
|
消息中间件 安全 NoSQL
阿里云通过中国信通院首批安全可信中间件评估
近日,由中国信通院主办的 2025(第五届)数字化转型发展大会在京举行。会上,“阿里云应用服务器软件 AliEE”、“消息队列软件 RocketMQ”、“云数据库 Tair”三款产品成功通过中国信通院“安全可信中间件”系列评估,成为首批获此认证的中间件产品。此次评估覆盖安全可信要求、功能完备性、安全防护能力、性能表现、可靠性与可维护性等核心指标,标志着阿里云中间件产品在多架构适配与安全能力上达到行业领先水平。
315 195

热门文章

最新文章