静态初始化块是一个代码块,在类的初始加载时由 JVM 执行,在首次使用任何静态成员或创建类实例之前。
问题背景:
从一开始,Java 就提供了静态字段来存储所有实例共享的值。为了进行非传统的初始化或在类启动时进行复杂的计算,引入了静态块。
问题:
普通的静态字段可以在声明时直接初始化,但当初始化过程较长、需要访问其他类/文件/数据库,或者依赖复杂逻辑时,就需要使用静态块。不当使用静态块可能导致类加载时出现意外行为、测试困难,甚至死锁。
解决方案:
静态块仅用于复杂的静态资源初始化,这些资源无法用一个表达式来表达。一个好的例子是加载 JDBC 驱动程序,读取配置文件:
public class Config { public static Properties properties; static { properties = new Properties(); try (InputStream in = new FileInputStream("config.properties")) { properties.load(in); } catch (IOException e) { throw new ExceptionInInitializerError(e); } } }
关键特点:
可以在静态块中使用 return 吗?
不可以,静态块中不允许使用 return 语句。可以使用 throw 抛出异常。
静态块是在类加载时执行还是在创建对象时执行?
静态块在类加载时执行一次,即使没有创建任何对象。
一个类中可以有多个静态块吗?它们的执行顺序是什么?
可以声明多个静态块。它们按代码中出现的顺序执行。
在类的静态块中读取一个大文件并连接到外部服务。在测试或简单的工具中,JVM 加载该类的速度很慢。
优点:
缺点:
静态块在启动时检查软件许可,如果出错,则抛出 ExceptionInInitializerError。
优点:
缺点: