父类未实现Serializable时,其字段不会被序列化;子类实现该接口仅序列化自身字段,父类字段在反序列化时通过无参构造器初始化为默认值(null/0/false),需手动通过writeObject/readObject补救或让父类实现接口。

父类未实现 Serializable 时,字段不会被序列化
Java 序列化机制只处理显式声明 implements Serializable 的类所定义的字段。如果父类没有实现该接口,哪怕子类实现了,父类中声明的所有实例字段(包括泛型参数如 ID id)在序列化过程中都会被跳过——既不写入字节流,也不参与反序列化重建。
反序列化时,JVM 会调用父类的无参构造器(必须存在且可访问)来初始化父类部分,此时所有未序列化的字段都按 Java 默认规则赋值:null(引用类型)、0(数值类型)、false(布尔类型)。
子类能否补救?可以,但需手动控制
当无法修改父类(比如它是第三方库中的类),子类可以通过自定义 writeObject 和 readObject 方法接管父类字段的序列化逻辑:
- 在
writeObject中先调用defaultWriteObject()序列化子类自身字段,再用out.writeXXX()显式写出父类字段值 - 在
readObject中先调用defaultReadObject()恢复子类字段,再用in.readXXX()逐个读回父类字段并赋值 - 要求父类必须有可访问的无参构造器,否则反序列化会抛出
InvalidClassException
最稳妥的修复方式:让父类也实现 Serializable
如果父类代码可控,直接让它实现 Serializable 并添加 serialVersionUID 是最简洁、安全的做法:
- 避免手动序列化带来的维护成本和出错风险
- 泛型类需注意:即使带类型参数(如
Entity<id></id>),只要声明了接口,其字段就能被正常序列化 - 子类仍建议显式声明
serialVersionUID,防止因父类版本变化导致兼容性问题
继承链中任意一级未实现 Serializable 都会中断字段传递
序列化不是“向上继承”的能力,而是逐类检查的契约。例如:
- A → B → C,只有 C 实现了
Serializable:那么只有 C 的字段被保存,B 和 A 的字段全部丢失 - A → B → C,A 和 C 实现了,B 没有:A 的字段能保留(因 A 自身可序列化),B 的字段丢失,C 的字段保留
- 只要某一级父类缺失接口且不可修改,就必须在最近的可修改子类中用自定义方法兜底

















