java中需自定义writeobject与readobject,因默认序列化会递归保存所有非transient、非static字段,而实际需跳过敏感字段、加密数据、重建资源或兼容版本变更;二者必须为private且签名严格固定,jvm通过反射调用,可配合defaultwriteobject/defaultreadobject复用默认逻辑并插入自定义处理。

Java 序列化中,通过自定义 writeObject 和 readObject 方法,可以精细控制对象的序列化与反序列化过程,比如跳过敏感字段、加密数据、兼容版本变更或执行初始化逻辑。
为什么需要自定义 writeObject 与 readObject
默认序列化会递归保存所有非 transient、非 static 字段,但实际开发中常需:
- 排除某些字段(即使没标
transient) - 对字段做预处理(如压缩、加密、转换格式)
- 保证反序列化后对象状态合法(如重建不可变引用、恢复线程不安全资源)
- 向后兼容旧版本序列化数据(如新增字段时提供默认值)
基本写法与调用时机
两个方法必须是 private void 签名,且参数固定:
-
private void writeObject(ObjectOutputStream out) throws IOException:在默认序列化前被自动调用 -
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException:在默认反序列化前被自动调用
注意:它们不会被继承,也不会被重载;JVM 通过反射精确匹配签名。若想复用默认行为(比如只干预部分字段),需在方法内显式调用 defaultWriteObject() 或 defaultReadObject()。
典型使用场景与代码示例
假设有一个用户类,含密码字段(不希望直接序列化)、缓存字段(无需保存)、以及一个需校验的邮箱字段:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String password; // 敏感字段
private transient String cache; // 已用 transient,但还想加日志
private String email;
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject(); // 先序列化 name、email(password 被 transient 自动跳过)
out.writeUTF("REDACTED"); // 显式写入占位符,避免反序列化时错位
System.out.println("Custom write: password masked");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject(); // 先读 name、email
String ignored = in.readUTF(); // 读掉占位符
this.cache = "fresh"; // 反序列化后重建瞬态字段
if (!email.contains("@")) {
throw new InvalidObjectException("Invalid email format");
}
}
}
关键点:
-
defaultWriteObject()必须在自定义写逻辑前调用,否则字段顺序错乱会导致反序列化失败 -
defaultReadObject()后可安全访问已还原的字段(如校验email) - 手动写的字段(如
writeUTF)必须和readUTF成对出现,数量与顺序严格一致
注意事项与常见陷阱
这两个方法看似简单,但容易踩坑:
- 不能是
public或protected,必须是private;否则 JVM 忽略,走默认流程 - 不能抛出未声明的异常类型(如
RuntimeException不用声明,但SQLException就得包装) - 若类有父类且父类也实现了
readObject,子类需主动调用super.readObject(in)(但通常父类没实现,所以一般不调) - 涉及单例、线程局部变量、数据库连接等资源时,务必在
readObject中重新初始化,不能依赖序列化保存
不复杂但容易忽略细节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











