writeReplace方法在ObjectOutputStream.writeObject()调用前触发,用于返回替代对象并由其参与后续序列化;要求方法名为writeReplace、public、无参、返回Object且不抛受检异常。

writeReplace 是 Java 序列化机制中一个特殊方法,用于在对象真正被序列化前,将其替换成另一个对象。它不是用来“修改”原对象,而是返回一个**替代对象**,后续序列化过程会转而处理这个新对象。
什么时候触发 writeReplace
当一个类定义了 public Object writeReplace() 方法(无参、返回 Object),且该方法是可访问的(如 public),JVM 在执行 ObjectOutputStream.writeObject() 时,会先检查并调用它。只要该方法存在并能成功执行,返回的对象就会取代原对象进入序列化流程。
注意:该方法只影响序列化,不影响反序列化;反序列化时不会调用它,也不会自动调用 readResolve。
基本写法和关键规则
必须满足以下条件,JVM 才会识别并调用 writeReplace:
立即学习“Java免费学习笔记(深入)”;
- 方法名严格为 writeReplace
- 访问修饰符为 public
- 无参数,签名是 public Object writeReplace()
- 返回类型为 Object(或其子类型)
- 不能抛出受检异常(否则序列化失败)
示例:
class Person implements Serializable {private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Object writeReplace() {
// 返回一个轻量级代理对象,比如只保留 name
return new PersonProxy(name);
}
}
常用于哪些场景
规避敏感字段序列化:原对象含密码、连接等不可序列化或不应持久化的字段,通过 writeReplace 返回一个干净的副本。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
版本兼容与迁移:旧类结构已废弃,但需兼容老数据,可替换为新类实例(如 Person → PersonV2),并在 readResolve 中再做适配。
单例/规范对象保证:配合 readResolve 使用,确保反序列化后仍为唯一实例(例如枚举语义模拟)。
序列化性能优化:大对象(如含缓存、图结构)可替换为 ID 或摘要对象,由反序列化端按需加载。
和 readResolve 的配合关系
writeReplace 替换的是**序列化输出的对象**,readResolve 替换的是**反序列化构造出的对象**。二者独立生效,但常成对使用:
- writeReplace 把 A → B(序列化时)
- readResolve 把 B → C(反序列化后)
例如:你序列化一个 Person,writeReplace 返回 PersonDTO;反序列化得到 PersonDTO 后,它的 readResolve 可返回最终的 Person 实例(或统一管理的 Person 缓存对象)。
注意:readResolve 必须定义在 writeReplace 返回的那个类(即 PersonDTO)里,才有效。

















