Serializable是标记接口,无方法,仅标识类可序列化;需显式实现、声明serialVersionUID、用transient控制字段,并配对使用ObjectOutputStream/ObjectInputStream完成读写。

实现 Serializable 接口是 Java 对象持久化的最基础方式——它不依赖数据库或框架,直接把内存里的对象“存成文件”,下次启动时再“读回来”。关键不在写多少代码,而在理解三件事:类要标记可序列化、字段要可控、流要配对用对。
让类具备可序列化能力
Serializable 是一个空接口,没有方法,只起标识作用。JVM 看到这个标记,才允许你把对象写进流里。
- 必须显式声明 implements Serializable,否则调用 writeObject 会立即抛出 NotSerializableException
- 强烈建议手动添加 private static final long serialVersionUID = 1L; 字段。不加的话 JVM 会按类结构自动生成哈希值,一旦类改了字段名、类型或删了方法,反序列化就失败
- 如果类有父类且父类没实现 Serializable,那父类的字段不会被保存;反序列化时会调用父类的无参构造方法来初始化这些字段——所以父类得有可访问的 public/protected 无参构造器
控制哪些字段参与持久化
不是所有字段都该存下来。密码、临时计算结果、数据库连接等,既不该存,也不能存。
- 用 transient 修饰不需要持久化的字段(比如
transient String token;),序列化时自动跳过 - 静态字段(static)默认不参与序列化,因为它们属于类而非对象实例
- 只有非 transient、非 static 的实例字段会被默认序列化;如果字段类型是自定义类(如 Person 中包含 Address),Address 类也必须实现 Serializable
用对象流完成读写操作
序列化本质是把对象图转为字节流写入文件,反序列化则是从字节流重建对象。两头必须用配套的流,且顺序不能乱。
立即学习“Java免费学习笔记(深入)”;
- 写入:用 ObjectOutputStream 包裹 FileOutputStream,调用
writeObject(obj)—— 一行代码就能把整个对象(含引用的其他对象)存进文件 - 读取:用 ObjectInputStream 包裹 FileInputStream,调用
readObject(),返回 Object 类型,需强制转型 - 务必关闭流(推荐 try-with-resources),否则可能文件锁住或数据没真正刷盘
- 注意:多次 writeObject 写入同一文件,读取时必须按相同次数和顺序调用 readObject,否则类型错位或 EOFException
实际使用中的常见注意点
这套机制简单直接,但几个细节不处理好,运行时就会报错或数据丢失。
- 集合类(ArrayList、HashMap 等)本身已实现 Serializable,只要其中元素类型也支持,整个集合就能被完整保存
- 若需定制序列化逻辑(比如加密敏感字段、跳过某些校验),可定义私有方法
private void writeObject(ObjectOutputStream out)和private void readObject(ObjectInputStream in),并在里面调用 defaultWriteObject/defaultReadObject 保留默认行为 - 文件损坏、版本不匹配、类路径变更都会导致 ClassNotFoundException 或 InvalidClassException,加 serialVersionUID 是最有效的预防手段


















