Java对象序列化通过ObjectInputStream/ObjectOutputStream将对象转为字节流存文件,要求类实现Serializable接口并建议显式定义serialVersionUID;transient和static字段不参与序列化;需注意类结构一致性、环境匹配及资源对象不可序列化。

Java 中用 ObjectInputStream 和 ObjectOutputStream 实现对象持久化传输,本质是把内存中的对象“转成字节流存到文件”,再“从文件读回对象”。它不依赖数据库或 JSON,是 Java 原生支持的轻量级方案,适合配置、缓存快照、本地状态备份等场景。
类必须实现 Serializable 接口
只有标记为可序列化的类,才能被写入或读出。这个接口没有方法,纯属告诉 JVM:“我可以被拍平”。
- 在类声明中加上
implements Serializable - 强烈建议手动添加
private static final long serialVersionUID = 1L;,避免类字段增减后反序列化失败 - 若某个字段不该保存(如密码、临时计算值),用
transient修饰,它会被自动跳过 - static 字段也不参与序列化,因为它属于类,不属于某个具体对象
用 ObjectOutputStream 写对象到文件
它不是独立工作的,必须套在底层字节流(比如 FileOutputStream)上,才能真正落地。
- 构造方式固定:
new ObjectOutputStream(new FileOutputStream("data.ser")) - 调用
writeObject(obj)即可保存整个对象,包括其非 transient 成员和引用的其他对象(前提是那些类也实现了Serializable) - 多个对象可连续写入,但要注意后续读取时顺序和数量必须严格一致,否则会抛
EOFException - 务必调用
close()或flush(),否则数据可能卡在缓冲区没写进文件
用 ObjectInputStream 从文件还原对象
它是写入的逆过程,从文件读出字节流,重建出结构一致的新对象(不是原对象引用,也不走构造方法)。
立即学习“Java免费学习笔记(深入)”;
- 构造方式对应:
new ObjectInputStream(new FileInputStream("data.ser")) -
readObject()返回Object类型,需强制转为目标类型,例如(Person) ois.readObject() - 每次
writeObject对应一次readObject;写入了 3 个对象,就读 3 次,少一次或多一次都会异常 - 必须捕获
ClassNotFoundException,因为 JVM 要根据类名动态加载类定义;如果类路径缺失或版本不匹配,也会抛InvalidClassException
常见陷阱与实用提醒
看似几行代码就能跑通,但实际容易出错的地方集中在类结构和运行环境一致性上。
- 父类没实现
Serializable?那它的字段不会被保存,子类只负责自己那一层 - 集合里装了自定义对象?每个元素类型都得可序列化,
ArrayList本身可以,但它存的Student不行就不行 - 不要试图序列化线程、Socket、Connection 这类资源对象——它们是运行时状态,必须声明为
transient - 文件扩展名无硬性要求(.ser、.dat、.obj 都行),但统一命名能快速识别用途,比如
config_v2.ser


















