父类静态块一定先于子类静态块执行,这是jvm类加载机制强制保障的:子类首次主动使用时,会触发从顶层父类开始的完整静态初始化流程,按源码顺序依次执行父类、子类的静态变量赋值和静态代码块,且仅执行一次。

父类静态块一定先于子类静态块执行,这个顺序不是由代码书写位置决定的,而是 JVM 类加载机制强制保障的结果。
谁触发,谁启动整个继承链的初始化
只要子类被首次主动使用(比如 new Child()、调用 Child.staticMethod()、访问 Child.STATIC_FIELD),JVM 就会启动从顶层父类开始的完整静态初始化流程:
- 先完成父类的类初始化:按源码顺序执行父类所有静态变量赋值 + 静态代码块
- 再完成子类的类初始化:同样按源码顺序执行子类静态变量赋值 + 静态代码块
- 整个过程只发生一次,后续无论 new 多少对象或调用多少次静态方法,都不会重复
静态块不依赖 new,但会被子类“捎带”初始化
即使你没直接操作父类,只要第一次用到子类,父类静态块就会被提前执行。这是因为 JVM 要求:子类初始化前,父类必须已完成初始化。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 调用 Parent.doSomething() 不会触发 Child 的静态块
- 但调用 Child.doSomething() 一定会先触发 Parent 的静态初始化,再执行 Child 的
- main 方法写在子类里,会导致 JVM 启动时就加载子类,从而“看似”子类先出现——其实是父类被强制提前加载了
编译期常量是个例外
像 public static final int VERSION = 1; 这类基本类型常量,属于编译期常量,访问它不会触发任何类初始化。
- 但如果静态字段是通过方法赋值的,比如 public static final String CONF = loadConfig();,就会触发完整初始化流程
- 子类静态块中可以安全使用父类 public static 字段;反之,父类静态块不能依赖子类的静态状态
验证顺序最简单的办法
在父类和子类里各加一个打印语句的 static {} 块,然后在 main 中尝试不同操作:
- 先调用子类静态方法 → 父类 static 块先输出,子类紧随其后
- 再 new 子类实例 → 静态块不再输出,说明已执行完毕
- 最后 new 父类实例 → 不影响子类静态块(除非子类此前已被触发)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










