创建子类对象时执行顺序为:父类静态代码块→子类静态代码块→父类实例代码块→父类构造函数→子类实例代码块→子类构造函数;静态部分仅首次加载类时执行一次,实例部分每次new均按继承链父→子顺序执行。

创建子类对象时,Java 有一套严格、不可变的初始化顺序。它不是靠“猜”或“经验”,而是由 JVM 明确保障的执行流水线,涉及静态资源加载和实例初始化两个阶段。
静态代码块:只在类首次加载时运行一次
静态代码块(用 static {} 定义)属于类级别,随类加载而触发。父类静态块总在子类静态块之前执行,且整个 JVM 生命周期内仅执行一次。
- 类加载时机包括:第一次 new 对象、首次访问该类的静态成员、或首次调用其静态方法
- 若已加载过父类(比如先 new 过另一个子类),再创建新子类对象时,父类静态块不会重复执行
- 不同子类各自的静态块互不影响,各自在本类首次使用时才执行
实例代码块:每次 new 都执行,且早于构造函数
不带 static 的 { } 块是实例代码块,属于对象初始化的一部分。它插入在对应类的构造函数体之前,但晚于父类的同类流程。
- 多个实例代码块按源码中从上到下的顺序依次执行
- 即使构造函数里用了 this() 调用本类其他构造器,实例代码块也只执行一次——在最终选定的那个构造函数开始前完成
- 它可以访问静态成员和已声明的实例字段(包括尚未显式赋值的),但不能引用后声明的变量(编译报错)
构造函数:链式调用,super() 是隐式起点
构造函数不是初始化的起点,而是继承链中承上启下的环节。每个构造函数第一行默认或显式含有 super() 或 this(),由此决定执行路径。
立即学习“Java免费学习笔记(深入)”;
- 若未写 super(),编译器自动插入无参 super(),从而触发父类构造流程
- 父类构造函数执行前,父类的实例代码块必须已全部执行完毕
- 子类构造函数体内的代码,是当前类初始化流程的最后一步(针对本类而言)
完整顺序示例(new Child())
以一个典型的父子类结构为例,实际执行顺序如下:
- 父类静态代码块(仅首次)
- 子类静态代码块(仅首次)
- 父类实例代码块
- 父类构造函数
- 子类实例代码块
- 子类构造函数体
这个顺序固定、可复现,也是 JVM 确保对象安全构造的底层机制。理解它,能帮你准确定位初始化异常、避免空指针,以及合理安排字段赋值逻辑。


















