Java继承初始化是JVM分两阶段控制的流水线:类加载时自顶向下执行静态初始化(仅一次),对象创建时自顶向下进入、自底向上返回执行实例初始化(每次new都触发)。

Java继承中初始化不是简单按代码从上往下跑,而是由JVM在类加载和对象创建两个阶段分层控制的流水线过程。掌握它,关键在于分清“静态”和“实例”两类动作,以及它们各自在继承链上的触发时机与执行方向。
静态部分:类加载时一次性完成,父类优先
只要首次用到某个类(比如 new Child()、访问 Child 的静态字段、调用其静态方法),JVM 就会触发该类及其父类的静态初始化,且严格按继承链自顶向下推进:
- 先确保父类已完成整个静态初始化(包括静态变量默认值→显式赋值→静态块,按源码顺序)
- 再执行子类的静态变量默认值→显式赋值→静态块
- 整个过程只发生一次,后续再 new 多少次、调多少次静态方法,都不会重复执行
实例部分:每次 new 时逐层展开,父类构造器必须先完成
创建一个子类对象,本质是“自顶向下进入、自底向上返回”的递归流程。父类构造器执行完毕,子类才能继续:
- 进入 Parent 构造器前:Parent 实例变量设默认值 → 显式赋值和实例块(按代码顺序)→ 执行 Parent 构造函数体
- Parent 构造结束,控制权回到 Child:Child 实例变量设默认值 → 显式赋值和实例块(按代码顺序)→ 执行 Child 构造函数体
- 注意 super() 是隐式或显式的首条语句,它把当前执行流交给父类构造逻辑;没有它,编译不通过
字段与方法绑定差异:容易踩坑的关键细节
初始化过程中,字段访问是静态绑定(看声明类型),而方法调用是动态绑定(看实际运行时对象类型):
立即学习“Java免费学习笔记(深入)”;
- 父类构造器中调用 print(),即使子类重写了,也会执行子类版本——因为此时对象已是 Child 类型
- 但子类中同名字段 i 在父类构造期间尚未初始化,仍为 0,导致输出 0 而非预期值
- 这种“父类构造中调用被子类覆盖的方法”是常见陷阱,应避免在构造器中调用可被重写的方法
调试验证:用日志锚定每个环节
不要靠记忆猜顺序,直接加带标识的日志观察真实执行流:
- 在每个静态块开头打 “[S] Parent static”
- 在每个实例块开头打 “[I] Parent init”
- 在每个构造函数第一行打 “[C] Parent()”
- 在字段初始化方法(如 String s = load();)内部也加日志
- 预期输出模式为:S-P → S-C → I-P → C-P → I-C → C-C;若错位,说明存在静态依赖循环、this()干扰或初始化异常中断


















