使用静态init块

时间:2010-02-03 08:37:45

标签: java static-initializer

我知道静态初始化块是如何工作的 任何人都可以告诉我它的一些典型用途。

7 个答案:

答案 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)

  • 初始化集合静态 字段,如地图,列表,集等
  • 初始化基于setter的对象,它也是静态的

答案 4 :(得分:2)

JDBC驱动程序是一个受欢迎的示例

为什么需要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)

  • 静态块: - 当我们想在加载类时执行代码然后我们可以将代码放在静态块中...
  • init: - 当我们想要在启动类的对象时执行代码,那么我们可以将代码放在init块中....