静态块在类加载时执行一次,用于初始化复杂静态属性,支持多步操作、异常处理和日志;多个静态块按代码顺序执行,不能访问非静态成员,且执行时机晚于静态字段直接赋值。

静态块在类加载时执行,适合用来初始化静态属性,尤其当初始化逻辑较复杂、无法用简单赋值完成时。
静态块的基本用法
静态块用 static 关键字定义,不带方法名和参数,只有一对花括号。它在类第一次被加载(如首次访问静态成员或创建实例)时自动运行,且仅执行一次。
- 一个类可定义多个静态块,按出现顺序从上到下依次执行
- 不能直接访问非静态成员(实例变量或方法)
- 可以抛出异常,但只能是 RuntimeException 或声明 throws(需调用方处理)
初始化静态集合或复杂对象
比如预加载常量映射表、解析配置文件、建立连接池初始状态等,不适合写在字段声明行里:
示例:public class Config {
public static final Map<String, String> ENV_MAP;
static {
ENV_MAP = new HashMap<>();
ENV_MAP.put("dev", "development");
ENV_MAP.put("prod", "production");
ENV_MAP.put("test", "testing");
// 可以加日志、校验、IO操作等
if (ENV_MAP.isEmpty()) {
throw new RuntimeException("Failed to initialize ENV_MAP");
}
}
}
与静态字段初始化顺序的关系
静态字段声明时的直接赋值,会在对应静态块之前执行(按代码顺序)。合理安排顺序可避免“未初始化就使用”问题:
- 先执行字段声明处的表达式(如 static int a = getValue();)
- 再执行同位置之后的静态块
- 若静态块依赖某静态字段,确保该字段已在前面声明并初始化
替代方案对比:静态块 vs 静态方法
有时会用私有静态方法配合赋值(如 static final List<String> NAMES = initNames();),二者都能实现延迟初始化。区别在于:
- 静态块更灵活:支持多步操作、条件判断、异常处理、日志输出
- 静态方法更易测试和复用,但需额外声明方法且不能直接赋给 final 字段(除非返回值确定)
- 对简单初始化,优先用直接赋值;中等复杂度选静态块;高复用需求可封装为静态方法

















