java中static静态代码块在类初始化阶段执行且仅一次,按源码顺序执行,父类先于子类,用于一次性初始化静态资源,不可访问非静态成员,异常会导致类永久错误。

Java 中的 static 静态代码块并不是在“类加载”(Loading)阶段执行,而是在类的 初始化阶段(Initialization) 自动运行,且仅执行一次。它不依赖对象创建,只要 JVM 决定对这个类进行初始化,静态代码块就会按源码顺序执行。
静态代码块触发类初始化的常见场景
- 使用
new创建该类的第一个实例 - 访问该类的非编译期常量静态字段(例如
static int PORT = 8080;),但访问static final String ENV = "prod";不会触发 - 调用该类的静态方法
- 通过
Class.forName("ClassName")反射加载(默认initialize = true) - JVM 启动时直接运行含
main方法的主类
以下操作 不会 触发初始化,静态代码块也不会执行:
-
ClassName.class(获取 Class 对象) -
ClassLoader.loadClass() - 引用
static final编译期常量(如字面量字符串、基本类型常量)
静态代码块的执行特点
- 按照在类中定义的文本顺序依次执行
- 父类静态代码块一定先于子类执行(类初始化前,先确保父类已初始化)
- 所有静态代码块在整个 JVM 生命周期内只执行一次
- 可用于初始化静态变量、加载配置、注册驱动、初始化连接池等一次性操作
- 不能访问非静态成员(实例变量或方法),只能操作静态成员
示例说明执行顺序
class Parent {
static { System.out.println("Parent static block"); }
}
class Child extends Parent {
static { System.out.println("Child static block"); }
}
首次执行 new Child() 时输出:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
Parent static block Child static block
第二次 new Child() 时,两个静态代码块都不再执行。
注意异常处理
如果静态代码块中抛出未捕获异常(如 NullPointerException 或 ExceptionInInitializerError),该类将永久处于错误状态,后续任何对该类的主动使用都会抛出 NoClassDefFoundError,无法恢复。
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










