java对象流序列化需三要素:类实现serializable接口并声明serialversionuid,用objectoutputstream与objectinputstream配对操作,通过transient控制字段序列化。

对象流序列化是 Java 中实现面向对象变量状态持久化最直接、原生的方式。它不依赖第三方库,核心在于把内存中的对象“拍平”成字节流写入文件,再按需“复原”。关键不是记住语法,而是理解三件事:类要可序列化、流要配对使用、状态要可控。
让类具备序列化能力
只有实现了 Serializable 接口的类,其对象才能被 ObjectOutputStream 写出。这个接口是空的标记接口,不强制你写任何方法,但它告诉 JVM:“这个类的状态可以被保存”。
- 必须显式声明
implements Serializable,否则调用 writeObject 会抛出 NotSerializableException - 建议手动添加
private static final long serialVersionUID = 1L;字段,避免类结构微调后反序列化失败 - 用 transient 修饰的字段(如密码、临时缓存)不会被序列化,属于“状态白名单”控制手段
用对象输出流完成状态写入
ObjectOutputStream 不是独立工作的,它需要一个底层字节流(如 FileOutputStream)来承载数据。序列化过程本质是把对象图(包括引用的其他对象)转为二进制并写入文件。
- 构造方式固定:
new ObjectOutputStream(new FileOutputStream("data.dat")) - 调用
writeObject(obj)即可保存整个对象,包括其所有非 transient、非静态成员变量 - 如果对象中包含其他自定义类(如 Person 里有 Address),这些类也必须实现 Serializable,否则会报错
用对象输入流还原对象状态
反序列化是序列化的逆操作,从文件读取字节流,重建出结构、内容一致的 Java 对象。注意:它创建的是新对象,不是原对象的引用。
- 构造方式对应:
new ObjectInputStream(new FileInputStream("data.dat")) - 调用
readObject()返回 Object 类型,必须强制转换为目标类型(如(Person) ois.readObject()) - 捕获
ClassNotFoundException是必须的,因为 JVM 需要根据类名动态加载类定义
确保状态准确性的实用细节
序列化保存的是对象“快照”,但实际业务中常需控制哪些状态该留、哪些该丢、哪些要定制格式。
- 重写
toString()不影响序列化,但它能帮你快速验证反序列化后的对象内容是否正确 - 若需更精细控制(比如只保存部分字段或加密敏感字段),应改用 Externalizable 接口,自行实现 writeExternal/readExternal
- 文件扩展名无强制要求(.dat、.ser、.obj 均可),但建议统一命名便于识别用途
- 不要在序列化前后修改类字段名或类型,否则反序列化大概率失败;版本号(serialVersionUID)是应对小范围演进的安全绳











