Java静态字段初始化

lyn*_*nks 7 java static-methods initialization

我刚刚用了半个小时来解决这个问题,我已经设法修复了我的代码,但是我并不完全理解发生了什么,并且想知道是否有人可以对它进行说明.

我有一个utils类型类,它包含一些静态字段(例如数据库连接端点),这些字段由各种其他程序使用,具体取决于手头的任务.基本上是一个图书馆.

这就是它之前的样子(虽然仍然破碎);

//DBUtils.java
public final class DBUtils {

    private static DBConnection myDBConnection = spawnDBConnection();
    private static DBIndex myDBIndex = null;

    private static DBConnection spawnDBConnection() {
        //connect to the database
        //assign a value to myDBIndex (by calling a method on the DBConnection object) <- IMPORTANT
        //myDbIndex NOT NULL HERE
        System.out.println("database connection completed");
        //return the DBConnection object
    }

    public static searchDB(String name) {
        //use the myDBIndex to find a row and return it
    }
}
Run Code Online (Sandbox Code Playgroud)

简而言之,我使用静态spawnDBConnection()方法为myDBConnectionmyDBIndex分配值.这很好用,我的程序的第一个输出行总是"数据库连接完成",在spawnDBConnection()方法结束时myDBConnection或myDBIndex都不为null,一切都是应该的.

我的外部程序看起来像这样;

//DoSomethingUsefulWithTheDatabase.java
public final class DoSomethingUsefulWithTheDatabase {

    public static void main(String args[]) {
        DBUtils.searchDB("John Smith"); //fails with NullPointerException on myDBIndex!
    }
}
Run Code Online (Sandbox Code Playgroud)

这个对searchDB的调用发生在spawnDBConnection完成之后,我已经广泛使用了标准输出来显示这个.但是,一旦在searchDB方法中,myDBIndex的值为null!它是一个静态字段,它在spawnDBConnection结束时不为空,没有进行其他任务,现在它为null :(

简单的解决方法是删除"= null",因此字段声明现在看起来像;

private static DBIndex myDBIndex;
Run Code Online (Sandbox Code Playgroud)

为什么会有所作为?我完全被这个困惑了.

MBy*_*ByD 13

那是因为nullto 的分配myDBIndex是在之后完成的

private static DBConnection myDBConnection = spawnDBConnection();
Run Code Online (Sandbox Code Playgroud)

例如,覆盖分配 spawnDBConnection

顺序是:

  1. 声明字段myDBConnection,myDBIndex
  2. 初始化 myDBConnection = spawnDBConnection();

    其中包括调用spawnDBConnection和赋值的返回值myDBConnection

  3. 初始化myDBIndex(带null)

在第二个示例中,第3步不存在.


Jon*_*eet 7

为什么会有所作为?我完全被这个困惑了.

初始化程序spawnDBConnection正在运行,然后初始化程序myDBIndex正在运行.用于myDBIndex将值设置为null 的初始化程序.因为 spawnDBConnection将其设置为非null值之后发生了这种情况,最终结果是它为null.

尽量不要这样做 - 静态初始化程序调用的方法设置其他静态变量很奇怪.