父类静态块先于子类静态块执行,且各自仅运行一次;jvm类加载时按继承层级从顶层父类开始逐级向下初始化,静态变量赋值与静态代码块均严格按源码顺序执行。

父子类静态块执行顺序由JVM类加载机制决定:父类静态块先于子类静态块执行,且各自仅运行一次。
静态块只在类初始化时触发,且不可跳过
当程序首次主动使用某个类(如 new 子类()、调用子类静态方法、访问子类静态字段),JVM 就会启动该类及其父类的初始化流程。这个过程不是按代码书写位置,而是严格遵循继承层级——从最顶层父类开始,逐级向下到目标子类。
- 父类的静态变量赋值和静态代码块按源码顺序依次执行
- 父类初始化完成后,才轮到子类的静态变量赋值和静态代码块
- 整个过程对每个类只发生一次;后续再 new 多少对象、调用多少次静态方法,都不会重复执行
静态块执行不依赖对象创建,但会被子类触发
即使你只写 Child.staticMethod(),只要 Child 类尚未初始化,就会连带触发 Parent 类的静态初始化。这是因为 JVM 要求子类初始化前,父类必须已完成初始化。
- final static 基本类型常量(如 public static final int VERSION = 1;)是编译期常量,不会触发类初始化
- 但如果静态字段通过方法赋值(如 public static final String CONF = loadConfig();),则会触发完整初始化流程
- 调用父类的静态方法,不会导致子类初始化;只有直接使用子类才会启动子类及父类的静态块
验证顺序的最小实践写法
在父类和子类中各加一个带打印的静态块,再在 main 中安排不同调用方式:
- 先调用子类静态方法 → 观察父类静态块先输出,子类静态块紧随其后
- 再 new 子类实例 → 静态块不再重复输出,证明已执行完毕
- 最后 new 父类实例 → 不影响子类静态块,因子类尚未被主动使用(除非之前已触发)
常见误判点:main 类位置影响初始加载顺序
如果 main 方法写在子类里,JVM 启动时就会先加载该子类,从而提前触发父类静态初始化。这容易让人误以为“子类先加载”,其实是 JVM 强制保障“父类先行”的结果。
- 把 main 放在独立测试类中,能更清晰分离“类加载时机”和“对象创建时机”
- 多个静态块在同一类中,严格按源码自上而下的顺序执行,与是否被 super 或 this 调用无关
- 静态块内不能访问非静态成员(编译报错),但可安全初始化配置、单例、日志器等全局资源
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











