静态代码块在类首次被主动使用时执行且仅一次,触发条件包括new实例、调用static方法、访问非编译期常量static字段、class.forname反射加载或main类启动;jvm将其合并为方法按源码顺序执行,父类优先、线程安全。

静态代码块本身不“确保”初始化完成,而是由 JVM 类初始化机制强制保障——只要触发条件满足,它就必然在首次主动使用前执行完毕,且只执行一次。
触发时机决定执行前提
静态代码块不会在类被加载时立刻运行,而是在类首次被主动使用时才进入初始化阶段。以下任一操作都会触发该过程:
- 用 new 创建该类实例
- 调用该类任意 public static 方法
- 访问该类非编译期常量的 public static 字段(如 public static int PORT = 8080;,但 public static final String MSG = "ok"; 不会)
- 通过 Class.forName("X") 反射加载(默认 initialize=true)
- 该类含有 main 方法并作为程序入口启动
只要没发生上述任一行为,静态代码块就不会执行;一旦发生,JVM 就必须先完成整个类的初始化(包括所有静态变量赋值和静态块),才能继续后续操作。
执行过程受 JVM 严格管控
JVM 把一个类中所有静态变量显式赋值语句和 static {} 块按源码顺序合并成一个特殊方法
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 多个静态块严格按书写顺序从上到下执行
- 静态变量初始化(如 static String s = loadConfig();)与静态块交替执行,而非分批进行
- 若任一环节抛出未捕获异常,
中断,类进入“初始化失败”状态,后续任何主动使用都直接抛 ExceptionInInitializerError
继承关系中父类先行
当子类被首次主动使用时,JVM 强制先完成父类初始化:
- 先执行父类全部静态成员赋值和静态块
- 再执行子类全部静态成员赋值和静态块
- 这个顺序不可跳过、不可并发、不可重入
因此,只要子类的某个静态方法或字段被访问,父类的静态代码块一定早已执行完毕。
线程安全由 JVM 底层保证
多个线程同时首次调用 getInstance() 或访问静态字段时,JVM 会自动对
- 仅一个线程执行初始化逻辑
- 其余线程阻塞等待,完成后共享同一结果
- 无需手动加锁或 volatile,天然线程安全
这种机制让静态代码块成为实现单例、预热资源等场景的可靠选择,前提是不提前触发(比如在其他静态字段中 new 当前类)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










