子类单独实现serializable时父类字段不被序列化,反序列化通过父类无参构造器初始化字段为默认值;需确保父类有public无参构造器,否则抛invalidclassexception。

父类没实现 Serializable,子类单独实现接口后,父类字段不会被序列化——这是 Java 序列化的硬性规则。反序列化时,JVM 会调用父类的无参构造器重建父类部分,所有父类字段都变成默认值(null、0、false),不是“丢失”,而是压根没写进字节流。
必须保证父类有可访问的无参构造器
这是子类能成功反序列化的底线要求。如果父类只有带参构造器,或无参构造器是 private,反序列化会直接抛 InvalidClassException。
- 检查父类是否已声明 public 无参构造器;没有就补上
- 若父类来自第三方库且不可修改,确认其源码中是否存在 public 无参构造器;否则无法走标准反序列化流程
首选方案:让父类也实现 Serializable
如果父类代码可控(比如你自己写的基类),这是最干净、安全的做法。
- 在父类声明处加上
implements Serializable - 显式添加
private static final long serialVersionUID字段 - 泛型类(如
Entity<id></id>)无需额外处理,字段自动纳入序列化范围 - 子类保持原样,不用改逻辑,也不用加手动读写方法
次选方案:子类重写 writeObject 和 readObject
适用于父类来自 SDK 或框架、完全不可修改的场景。
- 在子类中定义私有方法
private void writeObject(ObjectOutputStream out) throws IOException - 先调用
defaultWriteObject()序列化子类自身字段,再用out.writeXXX()显式写出每个父类字段 - 对应定义
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException - 先调用
defaultReadObject()恢复子类字段,再用in.readXXX()逐个读回并赋值给父类字段
注意继承链中的“中断点”
序列化不是向上继承的能力,而是逐级检查契约。例如:
- A → B → C,只有 C 实现了
Serializable:仅 C 的字段保留,A 和 B 全部不参与序列化 - A → B → C,A 和 C 实现,B 没实现:A 的字段能保留,B 的字段丢失,C 的字段保留
- 只要某一级父类不可改,就得由最近的可修改子类通过
writeObject/readObject兜底
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











