Cod*_*ler 6 java static static-methods nullpointerexception
启动时,我的程序立即抛出ExceptionInInitializerError.来源来自这种方法:
public static void errorMessage(String input) {
System.err.println("[ERROR] " + form.format(date) + " - " + Thread.currentThread().getStackTrace()[3].getClassName() + ": " + input);
}
Run Code Online (Sandbox Code Playgroud)
我打印出字符串的不同部分,发现只有在调用form.format(date)时才会抛出错误.它说它是空的.唯一的问题是,日期和表单都是在这个方法之上静态声明的,因为:
public static Date date = new Date();
public static DateFormat form = new SimpleDateFormat("HH:mm:ss");
Run Code Online (Sandbox Code Playgroud)
在修复一些小错误之后,错误突然开始被抛出.我不知道出了什么问题或者出了什么问题.我的意思是,我在同一个类中调用静态声明的变量.从技术上讲,它们不应该是空的,但它们是.任何人有任何想法,为什么它会抛出这个错误?这是控制台输出:
java.lang.ExceptionInInitializerError
at A$$OpSystem.getOperatingSystem(A$.java:98)
at A_.<clinit>(A_.java:19)
Caused by: java.lang.NullPointerException
at A$.errorMessage(A$.java:72)
at A$.loadCursor(A$.java:84)
at A$.<clinit>(A$.java:62)
... 2 more
Exception in thread "main"
Run Code Online (Sandbox Code Playgroud)
顺便说一句,A $ .OpSystem.getOperatingSystem只在那里显示,因为它调用A $ .errorMessage ...
我之前遇到过这个问题,就是当一个静态声明的变量在被调用时实际上从未声明为null时.现在它不应该是null,但它确实是.所以我不知道是什么导致了它.想法?
但我想这是一个了解静态变量如何实际加载的好时机......
编辑:如果我将调用'loadCursor'的静态Cursor对象移动到另一个类,似乎没有抛出异常.什么?
我对这种情况进行了测试但它没有返回任何错误?
public class StaticMethodTesting {
public static int i = getInt();
public static int getInt() {
return getAnotherInt();
}
public static int getAnotherInt() {
return 0;
}
public static void main(String[]args) {
System.out.println("Hi");
}
}
Run Code Online (Sandbox Code Playgroud)
检查异常跟踪后...
at A$.errorMessage(A$.java:72)
at A$.loadCursor(A$.java:84)
at A$.< clinit>(A$.java:62)
Run Code Online (Sandbox Code Playgroud)
它变得清晰,在某些静态字段初始化A$
时的初始化之前执行date
,并form
和通话loadCursor
,然后在逻辑上失败,NullPointerException
作为date
和form
不会被初始化.
问题是你已经放置了Cursor
初始化你的date
和初始化你的form
对象的代码.根据Java语言规范的第§8.3.2.1节,在声明时具有赋值的静态字段按声明顺序初始化.
如果您阅读详细的初始化过程,特别是第12.4.2.9节,您会发现......
接下来,按文本顺序执行类的类变量初始值设定项和类的静态初始值设定项,或接口的字段初始值设定项,就好像它们是单个块一样.
所以,你可能会做这样的事情:
static Cursor cursor = loadCursor();
static Date date = new Date();
static DateFormat form = new SimpleDateFormat("HH:mm:ss");
static Cursor loadCursor() {
...
errorMessage("...");
...
}
Run Code Online (Sandbox Code Playgroud)
loadCursor
必须不之前调用date
和form
,如果你想为这个工作被初始化.
你的例子没有产生'错误'(是吧?)的原因是因为这两个方法都没有引用尚未初始化的字段.如果您想要的等效行为绝不是错误,请参阅以下内容(可在此处查看):
import java.util.Random;
public final class Example {
/* note if the below read: static final int value = rand.nextInt(),
this would be considered an illegal forward reference to rand */
private static final int value = next();
private static final Random rand = new Random();
private static int next() {
return rand.nextInt();
}
public static void main(final String[] argv) { }
}
Run Code Online (Sandbox Code Playgroud)
可以看出输出如下.
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at Example.next(Example.java:11)
at Example.<clinit>(Example.java:7)
Run Code Online (Sandbox Code Playgroud)