静态代码块在类首次主动使用时的初始化阶段执行且仅一次;按源码顺序与静态变量赋值交替执行,父类静态内容先于子类,编译期常量访问不触发,异常导致类永久初始化失败。

静态代码块执行顺序不是靠记忆口诀,而是由 JVM 类初始化阶段严格控制的:它在类首次被主动使用时执行一次,按源码从上到下与静态变量赋值交替运行,父类优先于子类。
静态代码块什么时候真正执行
它不属于类加载阶段,而是在「类初始化」(Initialization)阶段触发,前提是该类尚未完成初始化。以下任一操作都会成为首次主动使用,从而触发执行:
- 用 new 创建该类实例
- 调用该类的 public static 方法
- 访问该类的 非编译期常量的 public static 字段(如 public static int PORT = 8080;)
- 通过 Class.forName("X") 反射加载(默认 initialize=true)
- 该类作为程序入口(含 main 方法)启动
注意:public static final int X = 1; 这类编译期常量不触发初始化,直接内联,静态代码块完全跳过。
同一类中多个静态代码块怎么排顺序
它们和静态变量显式赋值语句(如 static String s = init();)混合在一起,严格按源码书写顺序从上到下交替执行:
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 先出现的静态变量赋值,就先执行其初始化表达式
- 紧接着遇到 static{},就立即执行其中代码
- 后续同理,顺序即声明顺序,不可覆盖、不可重排
若某个静态初始化中访问了后面才定义的静态字段,该字段此时值为默认值(null 或 0),不会编译报错,但可能引发运行时逻辑异常。
继承关系下父子类静态块谁先跑
只要触发子类的初始化(比如 new Child()),JVM 就会强制先完成父类的整个静态初始化流程:
- 先执行 Parent 类中所有静态变量赋值 + 静态代码块(按源码顺序)
- 再执行 Child 类中所有静态变量赋值 + 静态代码块(同样按源码顺序)
这个过程只发生一次。后续无论 new 多少次 Child 实例,或调用多少次 Child 的静态方法,静态块都不会再次执行。
异常会影响后续使用吗
如果任意静态代码块或静态变量初始化过程中抛出未捕获异常(如 NullPointerException、IOException),JVM 会标记该类为“初始化失败”状态。此后任何对该类的主动使用,都会直接抛出 ExceptionInInitializerError,不再尝试重新初始化。

















