writeReplace是Java序列化中用于在序列化前将对象替换为代理对象的实例方法,签名必须为public Object writeReplace() throws ObjectStreamException,由ObjectOutputStream自动调用,返回值将被实际序列化。

在 Java 序列化中,writeReplace 是一个特殊方法,用于在对象真正被序列化之前,将其替换成另一个对象(通常是代理或简化版本),从而控制序列化的实际内容。它不是接口方法,而是通过反射机制被 ObjectOutputStream 自动调用的约定方法。
writeReplace 方法的签名和触发时机
该方法必须是实例方法、无参、返回任意非 void 类型(通常返回要替代的代理对象),且访问级别为 public 或 protected(包内可见也可):
public Object writeReplace() throws ObjectStreamException
当 ObjectOutputStream 准备写入某个对象时,会检查该对象所属类是否定义了 writeReplace 方法。如果存在且可访问,就会先调用它,然后序列化其返回值,而不是原对象本身。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
典型使用场景:避免序列化敏感或不可序列化字段
比如一个持有数据库连接、线程锁或大缓存的对象,本身不可序列化,或不应在网络/磁盘中持久化完整状态。此时可通过 writeReplace 返回一个轻量级、可序列化的“替身”(如只含 ID 和类型信息的 DTO):
- 原对象保留运行时逻辑,但不参与序列化
- 代理对象仅包含反序列化所需的关键信息
- 反序列化后,通常配合
readResolve恢复为真实业务对象(可选,视需求而定)
一个具体示例:用 Proxy 替换复杂对象
假设有一个 UserSession 类,内部持有一个不能序列化的 HttpSession 引用:
public class UserSession implements Serializable {
private String userId;
private transient HttpSession httpSession; // 不可序列化
public UserSession(String userId, HttpSession session) {
this.userId = userId;
this.httpSession = session;
}
private Object writeReplace() {
return new UserSessionProxy(userId); // 返回可序列化的代理
}
}
// 可序列化的代理类
class UserSessionProxy implements Serializable {
private final String userId;
UserSessionProxy(String userId) {
this.userId = userId;
}
private Object readResolve() {
// 反序列化后,根据 userId 重建真实 UserSession(需上下文支持)
return new UserSession(userId, lookupHttpSession(userId));
}
}
注意:UserSessionProxy 中不需要 writeReplace,因为它本身已是可序列化且无副作用的简单对象。
注意事项和常见误区
writeReplace 只影响序列化行为,不影响反序列化流程;反序列化时得到的是代理对象,若需还原为原始类型,应在代理类中实现 readResolve。
- 方法名必须严格为
writeReplace,大小写、参数、返回类型都不能出错 - 不能在静态上下文中定义,必须是实例方法
- 若返回
null,序列化会抛出NotSerializableException - 父类定义的
writeReplace对子类生效,但子类可覆盖以提供不同替换逻辑

















