Java静态代码块用于类加载时执行一次全局初始化,语法为static{},按定义顺序执行,父类优先于子类,适用于配置加载、常量预计算等;需避免异常、跨类依赖、耗时操作及线程安全问题。

Java静态代码块用于在类加载到JVM时执行一次初始化逻辑,适合做全局、一次性、与实例无关的准备工作,比如配置加载、常量预计算、线程池创建等。
静态代码块的基本写法和触发时机
静态代码块用 static {} 定义,不带方法名、无参数、不能加访问修饰符。它在类第一次被主动使用时(如首次 new 实例、调用静态方法、访问静态字段等)由类加载器执行,且只执行一次。
- 多个静态代码块按定义顺序从上到下依次执行
- 静态变量初始化语句(如 static int x = 10;)也属于“静态初始化”,其执行顺序与静态代码块一致
- 父类静态代码块先于子类执行
典型应用场景:全局属性初始化
当某些配置或资源需要在程序启动初期就准备好,并被所有实例共享时,静态代码块比构造方法或普通初始化更合适。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 读取配置文件并缓存:如从 properties 或 YAML 加载数据库连接参数,赋值给 static final 字段
- 预热单例或工具对象:例如初始化一个全局使用的 ObjectMapper、Log4j Logger、或自定义缓存容器
- 注册回调或钩子:如向监控系统注册类级指标,在 JVM 关闭前清理资源(配合 Runtime.getRuntime().addShutdownHook())
注意事项和常见陷阱
静态代码块看似简单,但容易引发隐式依赖、初始化失败或线程安全问题。
- 若代码块中抛出未捕获异常(如 IOException、ClassNotFoundException),会导致 NoClassDefFoundError,该类后续无法使用
- 避免在其中调用尚未初始化的静态字段(可能为 null 或默认值),尤其跨类引用时要注意加载顺序
- 多线程环境下,JVM 保证静态初始化是线程安全的,但块内自行创建的资源(如 HashMap)仍需手动同步
- 不要在静态块中执行耗时操作(如网络请求、大文件读取),会阻塞类加载,拖慢启动速度
对比其他初始化方式
静态代码块不是唯一选择,需根据场景权衡:
- static final + 直接赋值:适合编译期可确定的常量(如 static final String ENV = "prod";)
- 静态内部类延迟加载:适用于需要懒加载的重量级单例(“Initialization-on-demand holder”模式)
- @PostConstruct 或 Spring @Bean(initMethod):在框架管理的 Bean 中更推荐用生命周期回调,而非硬编码静态块
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










