父类无参构造方法在子类反序列化时会被自动调用,但仅当父类未实现serializable接口;若父类实现了serializable,则其构造方法完全不会被调用。

父类无参构造方法在子类反序列化时**会被自动调用**,但前提是该父类**没有实现 Serializable 接口**;如果父类实现了 Serializable,则其构造方法**完全不会被调用**。
父类未实现 Serializable:必须有无参构造方法
当父类未实现 java.io.Serializable 时,JVM 在反序列化子类对象时,会尝试通过反射调用父类的**无参构造方法**来初始化父类部分的状态。这是因为父类字段不属于序列化数据范围,JVM 需要“重建”父类实例状态。
- 若父类**没有无参构造方法**(比如只定义了带参构造、或声明了 private 无参构造但未提供 public/default),反序列化将抛出
InvalidClassException或IllegalAccessException - 父类无参构造方法可以是
public、protected或包级可见(default),但不能是private - 该构造方法中的代码会被执行(例如打印日志、初始化字段),但父类中被序列化的字段值不会从流中恢复——因为父类本身不可序列化,其字段不参与序列化过程
父类实现了 Serializable:构造方法不执行
如果父类也实现了 Serializable,那么它和子类一样,整个对象图都由序列化机制统一还原,JVM **跳过所有构造方法**(包括无参构造),直接分配内存并填充字段值(通过反射设置)。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 此时父类是否有无参构造方法无关紧要,也不会被调用
- 父类字段会从字节流中正常还原,无需构造逻辑参与
- 这也是推荐做法:让继承链上所有可序列化的类都实现
Serializable,避免构造器依赖
如何安全控制父类初始化逻辑
若父类不可序列化但又需确保某些初始化逻辑被执行(比如资源注册、状态校验),不能依赖构造方法(因反序列化时可能失败或绕过),应改用:
-
readObject()方法:在子类中定义,反序列化末尾调用,可显式补全父类逻辑 -
serialPersistentFields+ 自定义序列化:精细控制哪些字段参与序列化 - 将父类设计为抽象基类,并要求子类通过
writeObject/readObject协作初始化
一个典型报错示例
假设父类:
class Parent {
final String name;
Parent(String name) { this.name = name; } // 没有无参构造
}
class Child extends Parent implements Serializable {
int value;
Child() { super("default"); }
}
对 Child 实例序列化后反序列化会失败,提示 “no valid constructor” —— 因为 Parent 不可序列化,又找不到可访问的无参构造。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










