静态代码块在类首次被主动使用并进入jvm初始化阶段时执行且仅一次;触发条件包括new实例、调用静态方法、访问非final静态字段、class.forname反射加载或子类初始化。

静态块不是在“类加载”那一刻就运行,而是在类首次被主动使用并进入初始化阶段时执行,且仅一次。它不依赖对象创建,也不随每次调用重复触发——关键在于区分“类加载过程”和“类初始化阶段”。
哪些操作会真正触发静态块执行
只有以下行为属于“主动使用”,才会让JVM进入初始化阶段,从而运行静态块:
- 用
new创建该类的第一个实例 - 调用该类的任意静态方法
- 访问该类定义的非
final static编译期常量的静态字段(例如public static String CONFIG = "dev";) - 通过
Class.forName("X")反射加载(注意:ClassLoader.loadClass("X")不触发) - JVM 启动时直接运行含
main()的主类 - 初始化子类时(会先确保父类已完成初始化)
静态变量与静态块的执行顺序很严格
它们不是“先全赋值、再统一执行块”,而是按源码从上到下交替执行:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
static String A = initA();和static { B = initB(); }写在一起时,谁在前谁先运行 - 若
initA()中访问了尚未执行的B,得到的是默认值(null或0),不是编译错误 - 父类静态内容总在子类之前执行,同一类中多个静态块也严格按书写顺序执行
什么情况下静态块根本不会运行
看似用了类,其实没触发初始化:
- 引用
public static final int PORT = 8080;这类编译期常量——值已被内联,类不初始化 - 仅写
A.class获取 Class 对象,不触发初始化 - 子类调用父类的
static final常量字段,父类也不会初始化 - 用
ClassLoader.loadClass("X")加载类,只完成加载和连接,跳过初始化
适合放什么,不适合放什么
静态块是做轻量、确定、一次性准备的理想位置,但容易踩坑:
- ✅ 适合:加载本地配置流(
Class.getResourceAsStream())、预填充不可变集合、构建基于类加载机制的单例、校验必要环境变量 - ❌ 避免:远程 HTTP 调用、等待线程结束、访问其他尚未初始化的静态资源(易循环依赖)、抛出未捕获异常(会导致后续所有访问都报
NoClassDefFoundError) - ⚠️ 注意:热部署、OSGi、DevTools 等场景下,同一类可能被多个类加载器加载,每个都会独立执行一次静态块
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










