writereplace方法用于序列化前动态替换对象,必须定义在被序列化类内部,签名是private object writereplace() throws objectstreamexception,jvm通过反射调用并用其返回值替代原对象参与后续序列化。

ObjectOutputStream 本身不直接提供“动态替换对象”的接口,但可以通过在待序列化类中定义 writeReplace() 方法,让 JVM 在序列化前自动调用它,返回一个替代对象——这才是真正起作用的机制。
writeReplace 是类自己的方法,不是 ObjectOutputStream 的配置
这个方法必须定义在**被序列化的类内部**(非静态、无参数、返回任意 Object),且访问修饰符为 public 或 protected。JVM 序列化时会反射检查该类是否有此方法,有则调用,并用其返回值代替原对象参与后续序列化流程。
- 方法签名必须严格为:
private Object writeReplace() throws ObjectStreamException - 不能是 static,不能带参数,返回类型必须是 Object(或其子类)
- 即使类实现了 Serializable,只要定义了 writeReplace,原对象实例就不会被写入字节流
典型用途:序列化时脱敏、升级兼容、代理替换
比如敏感字段不存、旧类映射到新类、或用更轻量对象替代复杂实例:
- 用户类含密码字段?
writeReplace可返回一个不含密码的UserDTO实例 - 老版本
Person类已废弃?可返回新设计的PersonV2对象,保持反序列化兼容 - 想把单例对象序列化为标识符?返回一个包含 name/id 的 String 或 IDHolder 即可
注意 writeReplace 和 writeObject 的协作关系
如果同时定义了 writeReplace 和 writeObject,JVM 优先调用 writeReplace;只有它返回 null 时,才继续走 writeObject 流程。因此,writeReplace 是更高优先级的“前置拦截”。
-
writeReplace返回 null → 原对象继续走默认或自定义 writeObject -
writeReplace返回非 null 对象 → 该对象被传给 ObjectOutputStream,原对象彻底丢弃 - 替代对象自身若也支持 writeReplace,会再次触发递归替换(需小心循环)
替代对象必须可序列化,否则抛 NotSerializableException
writeReplace 返回的对象,会被 ObjectOutputStream 正常序列化。所以它要么实现 Serializable,要么是 JDK 内置可序列化类型(如 String、Integer),否则运行时报错。
- 返回 new ArrayList() ✅(ArrayList 实现 Serializable)
- 返回 new Date() ✅(Date 可序列化)
- 返回 new MyCustomClass() ❌(除非 MyCustomClass 实现 Serializable)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











