父类static代码块一定先于子类执行。jvm在子类首次主动使用时,强制按继承链从顶向下初始化:先父类静态变量与static块(按源码序),再子类对应部分;仅执行一次,且编译期常量访问不触发初始化。

父类 static 代码块一定先于子类 static 代码块执行。
执行顺序由 JVM 类加载机制强制保障
这不是靠代码位置或人为控制,而是 JVM 在类初始化阶段的硬性规则:
- 只要子类被首次主动使用(如
new Child()、调用Child.staticMethod()、访问Child.STATIC_FIELD),JVM 就会启动整个继承链的初始化 - 初始化从最顶层父类开始,逐级向下:先完成父类的静态变量赋值和静态代码块(按源码顺序),再执行子类的对应部分
- 整个过程只发生一次,后续任何操作都不会重复触发静态块
静态块不依赖 new,但会被子类“捎带”触发
即使你没直接引用父类,只要第一次用到子类,父类静态块就会提前执行:
- 因为 JVM 要求:子类初始化前,父类必须已完成初始化
- 调用
Parent.doSomething()不会触发Child的静态块 - 但调用
Child.doSomething()一定会先触发Parent的静态初始化,再执行Child的
验证方式简单直接
在父类和子类中各加一行打印的 static{},然后在 main 中尝试不同操作:
- 先调用子类静态方法 → 输出顺序是“父类 static”、“子类 static”
- 再 new 子类实例 → 静态块不再输出,说明已执行完毕
- 最后 new 父类实例 → 不影响子类静态块(除非子类此前已被触发)
注意编译期常量这个例外
像 public static final int VERSION = 1; 这类基本类型常量,属于编译期常量,访问它不会触发任何类初始化;但若写成 public static final String CONF = loadConfig();,就会触发完整初始化流程,包括父类和子类的静态块。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











