Java:什么是静态{}?

Java:什么是静态{}?,java,static-initializer,Java,Static Initializer,有人能给我解释一下下面是什么吗 public class Stuff { static { try { Class.forName("com.mysql.jdbc.Driver"); } catch ( ClassNotFoundException exception ) { log.error( "ClassNotFoundException " +

有人能给我解释一下下面是什么吗

public class Stuff
{
    static
    {
        try
        {
            Class.forName("com.mysql.jdbc.Driver");
        }
        catch ( ClassNotFoundException exception )
        {
            log.error( "ClassNotFoundException " + exception.getMessage( ) );
        }
...
}
这个静态{…}做什么

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


这个东西什么时候执行?

静态块被称为a-它在类第一次加载时运行(这是它唯一一次运行[footnote])

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



[脚注]静态块在加载类的每个类加载器上运行一次(因此,如果您有多个彼此不同的类加载器(例如,不委托)静态初始值设定项块的主要用途是在构造函数内部执行各种可能不合适的初始化,以便构造函数和初始值设定项一起将新创建的对象置于完全一致的使用状态

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


还请注意,静态初始值设定项是按照它们在源文件中以文本形式出现的顺序执行的。此外,在这些块中不能执行的操作也有很多限制,例如不使用选中的异常、不使用return语句或this和super关键字。

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

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版本的闭包时很有用。

每当第一次加载类时,就会执行静态初始值设定项块。如果更高级别的某件事正在执行
类35; forName(“yourpackage.YourClass”)
新建YourClass()
首次对相关课程进行测试

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

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

因此,每当您执行
Class.forName(“somepackage.ThisDriver”)时
,您将在
DriverManager
中有效地注册驱动程序,以便以后可以从中获得连接。

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

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


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

静态初始化块

  • 是一个普通的代码块

  • 它用大括号{}括起来

  • 它前面是static关键字

    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;
    }
}

“它在类第一次加载时运行(这是它唯一一次运行)。”-它不是每个加载类的类加载器运行一次吗?技术上我知道,但可能值得一提。在这种情况下,检查MySQL驱动程序并不是全部工作:实例化类会自动将其注册到DriverManager。这是在以后的DB connect()中响应MySQL URL所必需的如果catch子句抛出RunTimeException而不是仅仅记录错误,则类内容的加载将中止,对它的任何引用都将导致运行时出现NoClassDefFoundError。静态初始值设定项块(与构造函数和普通初始值设定项块相反)实际上与object initialization.Dupe无关。