Java继承初始化顺序由JVM类加载和对象创建两阶段驱动:先执行父类静态块再子类静态块(仅一次),然后按“父类实例块→父类构造器→子类实例块→子类构造器”顺序每次new都执行。

Java继承初始化顺序不是靠背步骤,而是由JVM类加载和对象创建两个阶段自然驱动的。父类静态块一定先于子类静态块执行,这个“先”不是代码书写位置决定的,而是JVM加载类时强制遵循的继承链顺序——必须先完成父类的静态初始化,才能开始子类的。
静态部分只跑一次,且严格按继承链从上到下
只要子类被首次主动使用(比如 new Child()、调用 Child 的静态方法或访问 Child 的静态字段),JVM就会触发整个继承链的静态初始化:
- 先为父类分配类数据结构,执行其所有静态变量赋值 + 静态代码块(按源码从上到下)
- 再为子类分配类数据结构,执行其所有静态变量赋值 + 静态代码块(同样按源码顺序)
- 整个过程与 new 多少次对象无关,静态部分终身只执行一次
实例部分每次 new 都走完整流程,但依赖静态前提
静态初始化完成后,才进入对象创建阶段。此时每 new 一个子类对象,都会触发完整的实例初始化流水线:
- 先为对象分配内存,所有实例变量设默认值(int=0、引用=null)
- 然后执行父类的实例变量赋值 + 实例代码块(按源码顺序)
- 接着调用父类构造器(隐含 super(),它内部又会先处理完父类自己的实例块)
- 再执行子类的实例变量赋值 + 实例代码块
- 最后运行子类构造器主体
容易踩坑的关键细节
这些地方不注意,轻则输出错乱,重则空指针或逻辑错误:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 静态代码块里不能访问非静态成员(编译直接报错),但可以安全初始化 static final 常量或加载配置文件
- 实例代码块在构造器之前执行,适合做多个构造器共用的初始化逻辑,比如统一设置默认状态
- 如果父类构造器里调用了被子类重写的方法,而该方法又访问了子类的实例变量,此时变量还是默认值(尚未赋值),极易引发 NPE
- 同一类中多个静态块、多个实例块,都严格按它们在源码中出现的先后顺序执行
验证用的最小可运行示例
这段代码能清晰印证顺序:
class Parent {static { System.out.println("Parent static"); }
{ System.out.println("Parent init"); }
Parent() { System.out.println("Parent ctor"); }
}
class Child extends Parent {
static { System.out.println("Child static"); }
{ System.out.println("Child init"); }
Child() { System.out.println("Child ctor"); }
}
执行 new Child() 输出为:
Parent static
Child static
Parent init
Parent ctor
Child init
Child ctor

















