java类初始化顺序严格遵循jvm强制流程:父类静态→子类静态→父类实例块→父类构造器→子类实例块→子类构造器,确保父类先就位、子类后执行。

静态部分:父类加载完成,子类才开始
只要子类被首次主动使用(比如 new Child()、调用 Child.staticMethod() 或访问非编译期常量的 Child.STATIC_FIELD),JVM 就会立即启动整个继承链的静态初始化,且严格按层级从上到下:
- 先执行父类中所有静态变量赋值(按源码顺序)
- 再执行父类中所有静态代码块(同样按出现顺序)
- 父类静态全部完成后,才轮到子类的静态变量赋值和静态代码块
这个过程只发生一次。哪怕之后反复 new 子类对象,或多次调用子类静态方法,静态块也不会重跑。
实例部分:每次 new 都重走完整父子链
静态初始化完毕后,才真正进入对象创建阶段。每 new 一个子类对象,JVM 都会完整执行以下步骤:
- 为对象分配内存,所有实例变量设默认值(int=0、Object=null)
- 执行父类的实例变量显式赋值 + 实例代码块(按源码顺序)
- 调用父类构造器(子类构造器首行隐含或显式 super())
- 父类构造器返回后,再执行子类的实例变量显式赋值 + 实例代码块
- 最后执行子类构造器主体
注意:父类构造器执行时,子类的任何实例字段都还是默认值——因为子类的实例初始化还没开始。
关键配合点:避免父类依赖子类未初始化的状态
最容易出问题的地方,是父类构造器里调用了被子类重写的方法。此时虽然执行的是子类方法体,但子类的实例字段尚未赋值,仍为默认值:
- 比如子类有 String name = "Alice";,但在父类构造器中调用 getName()(子类重写版),拿到的可能是 null
- 静态代码块里不能访问 this 或普通字段,编译直接报错
- 多个实例代码块按书写顺序执行,和构造器是否带 return 无关
这种配合不是可选的协作,而是 JVM 强制保障的执行链条:父类静态 → 子类静态 → 父类实例块 → 父类构造器 → 子类实例块 → 子类构造器。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











