
在 Java IO 体系中,对象流(ObjectInputStream/ObjectOutputStream)是处理对象持久化的核心工具,它通过序列化机制实现对象与字节流的相互转换。本文将从底层原理到实战应用,全面解析对象流的工作机制、序列化规范及最佳实践。
一、什么是对象流?
对象流是 Java 提供的专门用于操作对象的 IO 流,包含两个核心类:
- ObjectOutputStream:将对象转换为字节序列(序列化)
- ObjectInputStream:将字节序列还原为对象(反序列化)
它们的类继承关系如下:

对象流的特殊之处在于:
- 不仅能处理基本数据类型,更能直接操作对象
- 依赖序列化机制实现对象状态的持久化
- 是实现 RPC、分布式通信的基础技术之一
二、序列化与反序列化的核心原理
2.1 序列化的本质
序列化(Serialization)是将对象的状态信息转换为可存储或传输的字节序列的过程。它解决了对象跨平台传输、持久化存储的核心问题。

2.2 Serializable 接口的作用
Java 通过Serializable接口标识一个类可以被序列化,这个接口是一个标记接口(Marker Interface),没有任何方法定义:
java
public interface Serializable {
// 空接口,仅作为标记
}
实现该接口意味着:
- 类同意其对象可以被序列化
- 类的所有非瞬时(non-transient)非静态成员变量都会被序列化
- 子类若要被序列化,父类要么实现 Serializable,要么提供无参构造方法
三、对象流的基本使用
3.1 序列化操作(ObjectOutputStream)
java
// 定义可序列化的类
class User implements Serializable {
private String name;
private int age;
// transient修饰的字段不会被序列化
transient String password;
// 构造方法、getter、setter省略
}
// 序列化过程
public static void serialize() throws IOException {
User user = new User("Alice", 25, "123456");
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("user.ser"))) {
oos.writeObject(user);
System.out.println("对象序列化完成");
}
}
3.2 反序列化操作(ObjectInputStream)
java
// 反序列化过程
public static void deserialize() throws IOException, ClassNotFoundException {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("user.ser"))) {
User user = (User) ois.readObject();
System.out.println("反序列化结果: " + user);
// password字段会是null,因为被transient修饰
}
}
3.3 序列化流程解析

四、 serialVersionUID 的重要性
serialVersionUID是序列化机制中用于版本控制的关键标识:
java
class User implements Serializable {
// 显式声明序列化版本号
private static final long serialVersionUID = 1L;
private String name;
private int age;
}
它的作用是:
- 确保反序列化时使用的类与序列化时的类版本一致
- 若未显式声明,JVM 会根据类结构自动生成
- 类结构发生变化时,自动生成的 UID 会改变,导致反序列化失败

最佳实践 :所有可序列化类都应显式声明serialVersionUID
五、高级特性与注意事项
5.1 自定义序列化
通过重写以下方法实现自定义序列化逻辑:
java
private void writeObject(ObjectOutputStream out) throws IOException {
// 默认序列化
out.defaultWriteObject();
// 自定义处理transient字段
out.writeUTF(encrypt(password)); // 加密后写入密码
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// 默认反序列化
in.defaultReadObject();
// 自定义恢复transient字段
password = decrypt(in.readUTF()); // 解密读取密码
}
5.2 单例模式的序列化问题
单例对象序列化可能破坏单例性,解决方案是实现readResolve():
java
private Object readResolve() throws ObjectStreamException {
// 返回单例实例,替代反序列化创建的新对象
return INSTANCE;
}
5.3 序列化的性能考量

5.4 序列化的安全风险
- 反序列化可能执行恶意代码(需验证输入来源)
- 敏感数据可能被泄露(需加密敏感字段)
- 可能导致拒绝服务攻击(需限制输入大小)
六、总结
对象流是 Java 实现对象持久化和网络传输的基础技术,掌握序列化机制对于理解分布式系统、缓存实现等高级概念至关重要。
核心要点:
- 实现 Serializable 接口是对象可序列化的前提
- 显式声明 serialVersionUID 确保版本兼容性
- transient 关键字控制字段是否序列化
- 可通过自定义方法扩展序列化行为
- 注意序列化带来的性能和安全问题
合理使用对象流,可以在分布式系统、缓存、会话管理等场景中发挥重要作用。在实际开发中,还需根据具体需求选择合适的序列化方案,平衡易用性、性能和安全性。
