反序列化成功需父类有可访问无参构造器,否则抛InvalidClassException;父类字段不参与序列化,恢复为默认值;补救方式为父类实现Serializable或子类重写writeObject/readObject。

子类实现 Serializable 而父类未实现时,序列化本身不会报错,但反序列化行为完全取决于父类是否具备可访问的无参构造器——这是整个流程能否走通的硬性前提。
父类必须有可访问的无参构造器
Java 反序列化机制在重建对象时,会沿着继承链向上查找第一个未实现 Serializable 的类,并强制调用它的无参构造器。如果该构造器不存在、是 private、protected(且子类不在同一包),或只有带参构造器,反序列化会直接抛出 InvalidClassException: no valid constructor。
- 父类声明
public Parent() {}→ 反序列化成功,父类字段重置为默认值(null、0、false) - 父类只有
public Parent(String id)→ 运行时报错,无法继续 - 父类无参构造器是
protected,子类与父类同包 → 可用;不同包 → 不可用
父类字段不会被自动序列化
父类未实现 Serializable,意味着它声明的所有实例字段(包括泛型字段如 ID id)都不会写入字节流,也不会参与反序列化恢复。这不是“丢失”,而是压根没进序列化流程。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 子类字段照常保存和恢复
- 父类字段在反序列化后一律为 Java 默认初始值
- 继承链中任意一级中断(比如 A→B→C,仅 B 未实现),都会导致 B 及其上层未实现类的字段全部跳过
补救方式:优先让父类实现接口
若父类代码可控,这是最简洁、安全、可维护的方案:
立即学习“Java免费学习笔记(深入)”;
- 给父类添加
implements Serializable - 显式声明
private static final long serialVersionUID - 子类无需改动,原有逻辑和字段序列化行为保持不变
- 泛型类(如
Entity<ID>)也自动纳入序列化范围
补救方式:子类自定义 writeObject / readObject
当父类来自第三方库、无法修改时,子类可通过重写两个私有方法手动接管父类字段:
-
writeObject中先调用defaultWriteObject()序列化子类字段,再用out.writeXXX()显式写出父类字段值 -
readObject中先调用defaultReadObject()恢复子类字段,再用in.readXXX()读回并赋值给父类字段(需通过反射、setter 或直接字段访问) - 前提是父类字段可访问,或提供 public/protected setter,且父类有可访问无参构造器供初始构建
- 注意:
super.writeObject(out)无效——父类没实现接口,根本不存在该方法

















