跳转到内容

Java ObjectOutputStream

来自代码酷


Java ObjectOutputStreamJava IO 体系中的一个关键类,属于 java.io 包,用于将Java对象的原始数据类型和图形(即对象及其引用的其他对象)序列化为字节流。通过 ObjectOutputStream,开发者可以将对象持久化存储到文件或通过网络传输,之后可通过 ObjectInputStream 反序列化恢复对象状态。

概述[编辑 | 编辑源代码]

ObjectOutputStream 实现了 ObjectOutput 接口,扩展了 DataOutput 接口,支持基本数据类型和对象的序列化。序列化后的数据格式是平台无关的,但要求目标对象实现 java.io.Serializablejava.io.Externalizable 接口。

核心特性[编辑 | 编辑源代码]

  • 对象序列化:将对象转换为字节流。
  • 嵌套对象处理:自动序列化对象引用的其他对象(递归处理)。
  • 版本控制:通过 serialVersionUID 管理序列化兼容性。

基本用法[编辑 | 编辑源代码]

以下是一个简单的示例,展示如何将对象序列化到文件:

import java.io.*;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class ObjectOutputStreamExample {
    public static void main(String[] args) {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
            Person person = new Person("Alice", 30);
            oos.writeObject(person); // 序列化对象
            System.out.println("对象已序列化到文件");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出

对象已序列化到文件

详细说明[编辑 | 编辑源代码]

构造函数[编辑 | 编辑源代码]

  • ObjectOutputStream(OutputStream out):创建对象输出流,绑定到指定的字节输出流(如文件或网络流)。

主要方法[编辑 | 编辑源代码]

方法 描述
writeObject(Object obj) 序列化对象到输出流。
writeInt(int val) 写入基本数据类型 int
flush() 强制刷新缓冲区数据到目标流。
close() 关闭流并释放资源。

序列化机制[编辑 | 编辑源代码]

序列化过程遵循以下规则: 1. 检查对象是否实现 Serializable。 2. 递归处理对象的所有非瞬态(transient)和非静态字段。 3. 写入类描述符和字段值到字节流。

graph TD A[开始序列化] --> B{是否实现 Serializable?} B -->|是| C[写入类元数据] B -->|否| D[抛出 NotSerializableException] C --> E[递归处理字段] E --> F[写入字段数据] F --> G[结束]

实际案例[编辑 | 编辑源代码]

场景:保存用户配置[编辑 | 编辑源代码]

假设需要保存应用程序的用户设置(如主题、语言等):

class UserSettings implements Serializable {
    private static final long serialVersionUID = 2L;
    String theme;
    String language;

    public UserSettings(String theme, String language) {
        this.theme = theme;
        this.language = language;
    }
}

public class SettingsManager {
    public static void saveSettings(UserSettings settings, String filename) throws IOException {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
            oos.writeObject(settings);
        }
    }

    public static void main(String[] args) {
        UserSettings settings = new UserSettings("Dark", "en_US");
        try {
            saveSettings(settings, "user_settings.ser");
        } catch (IOException e) {
            System.err.println("保存配置失败: " + e.getMessage());
        }
    }
}

注意事项[编辑 | 编辑源代码]

  • 安全性:反序列化未经验证的数据可能导致安全漏洞(如注入攻击)。
  • 性能:序列化大对象或深层次对象图可能消耗较多内存和CPU。
  • 兼容性:修改类定义(如删除字段)可能导致反序列化失败,需通过 serialVersionUID 显式管理版本。

高级主题[编辑 | 编辑源代码]

自定义序列化[编辑 | 编辑源代码]

通过实现 writeObjectreadObject 方法,可覆盖默认序列化行为:

private void writeObject(ObjectOutputStream out) throws IOException {
    out.defaultWriteObject(); // 默认序列化
    // 自定义逻辑(如加密字段)
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    in.defaultReadObject(); // 默认反序列化
    // 自定义逻辑(如解密字段)
}

瞬态字段[编辑 | 编辑源代码]

使用 transient 关键字标记不需要序列化的字段:

class Data implements Serializable {
    transient String temporaryCache; // 不会被序列化
}

总结[编辑 | 编辑源代码]

ObjectOutputStream 是Java序列化的核心工具,适用于持久化或传输对象状态。使用时需注意安全性、版本兼容性和性能问题。通过自定义序列化逻辑,可以灵活控制对象的存储格式。