Java:什么是static {}?

时间:2009-11-15 10:57:22

标签: java static-initializer

有人能解释一下以下是什么吗?

public class Stuff
{
    static
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
        }
        catch ( ClassNotFoundException exception )
        {
            log.error( "ClassNotFoundException " + exception.getMessage( ) );
        }
...
}

这静态{...}做什么?

我知道C ++中的静态变量,但这是静态块还是什么?

这些东西什么时候会被执行?

6 个答案:

答案 0 :(得分:14)

静态块称为class static initializer - 它在第一次加载类时运行(并且它是唯一一次运行[脚注])。

该特定块的目的是检查MySQL驱动程序是否在类路径上(如果不是则抛出/记录错误)。


[脚注]每个加载类的类加载器运行一次静态块(所以如果你有多个彼此不同的类加载器(例如,不委托),它将被执行一次。

答案 1 :(得分:8)

静态初始化程序块的主要用途是执行各种初始化操作,这些初始化可能不适合构造函数,因此构造函数和初始化程序将新创建的对象放在一个完全一致的状态下使用。

与构造函数相比,例如,静态初始值设定项不会被继承,并且只在JRE加载和初始化类时才执行一次。在上面的示例中,一旦初始化完成,类变量foo将具有值998877。

另请注意,静态初始化程序按它们在源文件中以文本方式显示的顺序执行。此外,对于其中一个块内部无法执行的操作存在许多限制,例如不使用已检查的异常,不使用return语句或this和super关键字。

答案 2 :(得分:1)

我想补充一点,静态变量和静态初始化程序是在类加载时按照出现的顺序执行的。因此,如果静态初始化程序依赖于某个静态变量,则必须在特定静态块之前初始化它,例如

final static String JDBC_DRIVER = getJdbcDriver( );

static
{
  try
  {
    Class.forName(JDBC_DRIVER);
  }
  catch ( ClassNotFoundException exception )
  {
    log.error( "ClassNotFoundException " + exception.getMessage( ) );
  }
}

在此示例中,getJdbcDriver将在静态初始化程序之前执行。此外,类中可能有多个静态初始化程序。他们再一次按照出现的顺序执行。

我还想在这里提到实例初始化器的存在,因为它们在第一次看到时确实令人惊讶。它们看起来像是类体内的代码块,就像这样。

class MyClass
{
  final int intVar;

  {
    intVar = 1;
  }
}

一般情况下,由于构造函数的使用,它们的使用有点不必要,但它们在实现Java的闭包版本时非常有用。

答案 3 :(得分:1)

每当第一次加载类时,都会执行静态初始化程序块。如果更高级别的某些内容首次在相关课程中执行Class#forName("yourpackage.YourClass")new YourClass(),就会发生这种情况。

巧合的是,体面的JDBC驱动程序内部也有类似的东西。它们使用静态初始化程序块在DriverManager中注册自己:

static {
    DriverManager.registerDriver(new ThisDriver());
}

这样,无论何时执行Class.forName("somepackage.ThisDriver"),您都会在DriverManager中有效地注册驱动程序,以便之后可以从中获取连接。

答案 4 :(得分:1)

除了上述所有内容之外,使用类构造函数和类初始值设定项还有一点不同。我们知道的构造函数通常用于初始化对象,如果我们有静态变量,那么通常使用静态块以便在加载类时初始化它们。

当我们有静态变量和静态块时,首先初始化静态变量然后初始化块。

首次加载类时,静态块在类构造函数之前初始化。

答案 5 :(得分:0)

静态初始化块

  • 是正常的代码块

  • 它括在大括号{}

  • 前面是静态关键字

    class Foo {
        static {
            // initialization code goes here:
            doSomething();
        }
    }
    
  • 类可以有任意数量的静态初始化块

  • 它们可以出现在课堂主体的任何地方

  • 按照代码

  • 中的出现顺序调用它们

静态初始化块有一种替代方法:

  • 编写私有静态方法
  • 并将其分配给静态类变量

这种方法的优点是可以在以后调用静态方法来重新初始化类变量。

class Foo {
    public static int myVar = initializeClassVariable();

    private static int initializeClassVariable() {
        // initialization code goes here:
        int v = 255;
        return v;
    }
}