静态代码块在类初始化阶段天然具有最高执行优先级,仅在jvm类初始化阶段(initialization)执行一次,按源码从上到下顺序与静态变量交替执行,父类静态部分先于子类,异常导致类永久初始化失败。

静态代码块在类初始化阶段的“优先级”不是靠显式设置高低来实现的,而是由 JVM 严格按固定规则执行——它天然具有最高执行优先级,但这个优先级体现在执行时机和顺序上,而非可配置的权重。
静态代码块的执行时机决定其实际优先级
它只在类的「初始化阶段」(Initialization)运行,且是该阶段最先被执行的部分。这个阶段本身就在类加载流程中靠后(位于 Loading、Linking 之后),但一旦触发,静态代码块就立即成为当前任务的核心:
- 类首次被主动使用时才触发(如 new 实例、调用 static 方法、访问非 final static 字段、Class.forName 等)
- 此时 JVM 会合成所有静态变量赋值语句和 static {} 块为一个
方法 - 该方法从源码顶部开始逐行执行:谁写在前面,谁先运行
同一类中多个静态代码块按书写顺序自然排序
它们之间没有“优先级标签”,但执行顺序完全确定:
- static int a = initA(); 写在前 → 先调用 initA()
- static { b = 20; } 写在后 → 后执行赋值
- 若中间插入 static final String C = "OK";(编译期常量),它不参与初始化,也不影响前后语句顺序
- 编译器禁止前向引用:不能在 static {} 中读取其后才声明的静态变量(编译报错)
继承关系下父类静态部分强制拥有更高执行次序
这不是人为指定的优先级,而是 JVM 初始化协议的一部分:
- 哪怕你直接 new Child(),JVM 也必须先完成 Parent 的整个
执行(含所有静态变量赋值和 static {}) - 只有 Parent 初始化成功后,才会进入 Child 的
- 这种层级约束不可绕过,也不受子类是否定义了 static 成员影响
- 若 Parent 初始化失败(抛出未捕获异常),Child 根本不会开始初始化
静态代码块无法让渡优先级给其他逻辑
它的高优先级也意味着限制:
- 不能调用非静态方法或访问实例字段(此时还没有 this)
- 不能依赖尚未初始化的其他类的静态成员(可能引发死锁或 NoClassDefFoundError)
- 耗时操作(如网络请求)会阻塞整个类初始化,影响后续所有对该类的使用
- 一旦抛出未处理异常,类进入“初始化失败”状态,后续任何访问都直接失败
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











