java类初始化顺序是“静态优先、父类先行、实例后置、构造收尾”:1.父类静态变量与静态块(按源码顺序)→2.子类静态变量与静态块→3.父类实例变量与实例块→4.父类构造器→5.子类实例变量与实例块→6.子类构造器。

Java中成员变量的初始化顺序确实是从父类到子类,但这只是整体流程的一部分。真正起作用的是“静态优先、父类先行、实例后置、构造收尾”这一整套分层机制。
静态成员先加载,父类静态优先于子类静态
当JVM首次主动使用某个类(比如通过new创建对象,或访问其静态字段/方法)时,会触发类加载与静态初始化。此时:
- 先加载父类:执行父类中所有static变量赋值语句和static{}代码块,按它们在源码中出现的顺序依次执行
- 再加载子类:同理执行子类的静态成员初始化
- 静态部分只执行一次,无论后续创建多少个对象
实例成员初始化紧随其后,仍遵循父类→子类
当调用new Derived()时,进入对象构造阶段。此时静态部分已完成,开始为每个新对象分配空间并初始化实例成员:
- 先为父类的普通成员变量赋予默认值(如int为0,Object为null)
- 再按声明顺序执行父类中的实例变量赋值(如int x = 5;)和实例代码块{...}
- 然后才调用父类构造器(即使没显式写super(),编译器也会自动插入)
- 父类构造器执行完后,才轮到子类:同样先赋值实例变量、执行实例块,最后调用子类构造器
注意:构造器里对成员的二次赋值不算“初始化”
成员变量的初始化是指JVM在构造器执行前完成的那一轮赋值和代码块运行。而构造器内部写的this.x = 10;属于运行期逻辑,不改变初始化顺序本身。例如:
class Parent { int a = 1; { a = 2; } Parent() { a = 3; } }
创建对象时,a的值变化是:默认0 → 赋值1 → 实例块变2 → 构造器变3。
继承链越长,顺序越清晰
如果有A → B → C三级继承,初始化顺序就是:
- A静态 → B静态 → C静态
- A实例变量/块 → A构造器
- B实例变量/块 → B构造器
- C实例变量/块 → C构造器
每一步都不可跳过,且无法通过子类代码绕开父类的初始化步骤。











