我刚刚花了半个小时弄清楚这件事,我已经设法修复了我的代码,但我不完全理解发生了什么,想知道是否有人可以阐明它。
我有一个 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
}
}
简单地说,我使用静态 spawnDBConnection() 方法为 myDBConnection 和 myDBIndex 赋值。这非常有效,我程序的第一行输出始终是“数据库连接已完成”,在 spawnDBConnection() 方法结束时 myDBConnection 或 myDBIndex 都不为空,一切都应该如此。
我的外部程序是这样的;
//DoSomethingUsefulWithTheDatabase.java
public final class DoSomethingUsefulWithTheDatabase {
public static void main(String args[]) {
DBUtils.searchDB("John Smith"); //fails with NullPointerException on myDBIndex!
}
}
这个对 searchDB 的调用发生在 spawnDBConnection 完成之后,我已经广泛使用标准输出来展示这一点。但是,一旦进入 searchDB 方法,myDBIndex 的值为空!它是一个静态字段,在 spawnDBConnection 结束时它不是 null,没有进行其他分配,现在它是 null :(
简单的修复是删除“= null”,这样字段声明现在看起来像这样;
private static DBIndex myDBIndex;
为什么会有所不同?我对此感到非常困惑。
最佳答案
那是因为null
对myDBIndex
的赋值是在
private static DBConnection myDBConnection = spawnDBConnection();
例如覆盖 spawnDBConnection
顺序是:
- 声明字段
myDBConnection
、myDBIndex
初始化
myDBConnection = spawnDBConnection();
其中包括调用
spawnDBConnection
并将返回值赋给myDBConnection
- 初始化
myDBIndex
(为空)
在你的第二个例子中,第三步不存在。
关于Java 静态字段初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11631216/