子类对象实例化时父类构造函数必须先执行——Java继承机制的底层约束,确保父类部分初始化完成后再执行子类代码,顺序为:父类静态→子类静态→父类实例变量/代码块/构造函数→子类实例变量/代码块/构造函数。

子类对象实例化时,父类构造函数必须先执行——这不是语法糖,而是 Java 继承机制的底层约束。它确保子类在获得自身初始化能力前,其继承自父类的部分已处于有效、可安全访问的状态。
父类构造必须“先行到位”
Java 规定:每个子类构造函数的第一条语句(显式或隐式)必须是 super() 或 this()。若未显式写出 super(...),编译器自动插入 super()(即调用父类无参构造)。这意味着控制权会立即转入父类构造流程,直到父类构造完全结束,才回到子类继续执行。
- 如果父类没有无参构造,而子类又没写
super(参数),编译直接报错 - 哪怕子类构造体为空,父类构造也必然先跑完;子类自己的代码永远在父类之后执行
- 这种“自顶向下进入、自底向上返回”的递归调用链,最终止于
Object类的构造
实例初始化阶段严格分层推进
构造函数只是实例初始化流程中的一环。真正完整的顺序还包含成员变量赋值和构造代码块,且全部按继承层级逐级展开:
- 先执行父类的实例变量默认值设定 → 父类构造代码块(按书写顺序)→ 父类构造函数体
- 再执行子类的实例变量默认值设定 → 子类构造代码块(按书写顺序)→ 子类构造函数体
- 构造代码块虽写在类里任意位置,但会被编译器“提升”到每个构造函数开头,在
super()之后、构造函数体之前运行
静态部分与实例部分分离执行
注意区分:父类构造函数的“优先执行”,仅针对每次 new 对象的实例化阶段。而更早发生的静态初始化(static 变量、static 代码块)是类加载时一次性完成的,顺序是:父类静态 → 子类静态,且只触发一次。
立即学习“Java免费学习笔记(深入)”;
- 静态内容不依赖对象创建,哪怕从没 new 过子类,只要首次主动使用(如调用静态方法),父类静态部分就已执行完毕
- 实例部分则每次 new 都完整走一遍“父类→子类”链条,二者互不干扰,但时间上静态一定早于任何构造调用
重写方法在构造中调用需格外谨慎
如果父类构造函数里调用了被子类重写的方法,实际执行的是子类版本——此时子类实例变量可能尚未初始化(仍为默认值),极易引发空指针或逻辑错误。
- 例如父类构造中调用
init(),而子类重写了它并访问了还未赋值的字段,结果不可预知 - 最佳实践:避免在构造函数中调用可被重写的方法;如必须调用,应声明为
final或private


















