9

我知道静态初始化块是如何工作的。
谁能告诉我它的一些典型用途。

4

7 回答 7

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 所指出的,静态初始化块会降低代码的可读性,因此请谨慎使用它们。静态方法更透明地做同样的事情。

于 2010-02-03T08:39:21.270 回答
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();
于 2010-02-03T08:38:58.523 回答
3

它们通常与JNI代码结合使用,以确保加载所需的本机库:

class MyJniConnection {

    public static native void myJniCall();

    static {
        System.load("native.dll");
    }
}
于 2010-02-03T08:48:30.247 回答
2
  • 初始化集合静态字段,如 Map、List、Set 等
  • 初始化同样是静态的基于 setter 的对象
于 2010-02-03T08:41:11.403 回答
2

JDBC 驱动程序是一个流行的例子

为什么需要Class.forName()将驱动程序加载到内存中。答案很简单。正如 JDBC 规范中规定的那样,所有 JDBC都有一个静态块,以便在加载类后立即Driver注册自己。像这样的东西:DriverManagerDriver

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.

于 2010-02-03T20:00:00.627 回答
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
于 2010-02-03T09:02:48.687 回答
0
  • 静态块:-当我们想在加载类时执行代码时,我们可以将代码放在静态块中......
  • init :- 当我们想在类的对象初始化时执行代码时,我们可以将代码放在 init 块中......
于 2013-05-22T16:05:23.553 回答