我知道静态初始化块是如何工作的 任何人都可以告诉我它的一些典型用途。
答案 0 :(得分:10)
如果要在一个地方初始化一个或多个静态变量
这很有用,因为您可以应用异常处理,这在内联初始化时是不可能的。
例如:
public static ImageIcon defaultIcon = ImageIO.read(..);
可以用
初始化public static ImageIcon defaultIcon;
static {
try {
defaultIcon = ImageIO.read(..);
} catch (IOException ex){
System.out.println("No default icon available");
}
}
另一个应用程序是复杂的初始化。例如,如果某个项目需要初始化多行代码。假设你有一个配置:
public static Configuration configuration;
static {
confuguration = new Configuration();
configuration.setSomething(..);
configuration.setSomethingElse(..);
...
}
第三种用法是初始化一些外部API基础结构。我当前项目的一个例子:
static {
org.apache.xml.security.Init.init();
}
但是,正如Mykola Golubyev所指出的那样,静态初始化块会降低代码的可读性,因此请谨慎使用它们。静态方法更透明地做同样的事情。
答案 1 :(得分:5)
尽量避免使用静态初始化块。相反,您可以使用私有静态初始化函数,这将使您的代码更加干净。
我将参考@Bozho的例子。
不要做
public static Configuration configuration;
static {
confuguration = new Configuration();
configuration.setSomething(..);
configuration.setSomethingElse(..);
...
}
改为使用
public static Configuration configuration = createConfiguration();
或
public static Configuration configuration = YourConfiguration.create();
答案 2 :(得分:3)
它们通常与JNI代码一起使用,以确保加载所需的本机库:
class MyJniConnection {
public static native void myJniCall();
static {
System.load("native.dll");
}
}
答案 3 :(得分:2)
答案 4 :(得分:2)
为什么需要Class.forName()
将驱动程序加载到内存中。答案很简单。根据JDBC规范的规定,所有JDBC Driver
都有一个静态块,只要加载DriverManager
类,就可以使用Driver
注册自己。像这样:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
所以,当你写(例如在这里使用MySQL驱动程序)时:
Class.forName("org.gjt.mm.mysql.Driver");
类加载器尝试加载和链接org.gjt.mm.mysql.Driver
类,如果成功,则执行静态初始化块,Driver
将自己注册到DriverManager
。
答案 5 :(得分:1)
它们可用于创建DSL,就像JMock那样。例如,要设置用户将保存到数据库的期望:
Mockery context = new Mockery();
final Database database = context.mock(Database.class);
...
context.checking(new Expectations() {{
oneOf(database).save(user);
}});
// Rest of the test
答案 6 :(得分:0)