启动时,我的程序会立即抛出ExceptionInInitializerError。来源来自这种方法:
public static void errorMessage(String input) {
System.err.println("[ERROR] " + form.format(date) + " - " + Thread.currentThread().getStackTrace()[3].getClassName() + ": " + input);
}
我打印出字符串的不同部分,发现只有在调用form.format(date)时才会抛出错误。它说它是空的。唯一的问题是,日期和表单都在这个方法的正上方静态声明:
public static Date date = new Date();
public static DateFormat form = new SimpleDateFormat("HH:mm:ss");
在修复一些小错误之后,错误突然开始被抛出。我不知道出了什么问题或者出了什么问题。我的意思是,我在同一个类中调用静态声明的变量。从技术上讲,它们不应该是空的,但它们是。任何人有任何想法,为什么它会抛出这个错误?这是控制台输出:
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"
顺便说一句,A $ .OpSystem.getOperatingSystem只在那里显示,因为它调用A $ .errorMessage ......
之前我遇到过这个问题,只是当一个静态声明的变量在被调用时实际上从未被声明为空时。现在它不应该是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");
}
}
答案 0 :(得分:7)
检查异常跟踪后......
at A$.errorMessage(A$.java:72)
at A$.loadCursor(A$.java:84)
at A$.< clinit>(A$.java:62)
很明显A$
中的某些静态字段初始化正在date
和form
的初始化之前执行,并且正在调用loadCursor
,然后NullPointerException
逻辑失败并date
1}} form
和Cursor
未初始化。
问题在于,您已经在初始化date
和form
对象之前放置了初始化static Cursor cursor = loadCursor();
static Date date = new Date();
static DateFormat form = new SimpleDateFormat("HH:mm:ss");
static Cursor loadCursor() {
...
errorMessage("...");
...
}
的代码。声明时具有分配的静态字段按声明顺序初始化,按Section §8.3.2.1 of the Java Language Specification。
如果你阅读详细的初始化过程,特别是Section §12.4.2.9,你会发现......
接下来,以文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就像它们是单个块一样。
所以,你可能会做这样的事情:
loadCursor
date
必须 才能在form
之前调用<{1}},并且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) { }
}
如果您希望这样做,则必须<{1}}。
你的例子没有产生'错误'(是吧?)的原因是因为这两个方法都没有引用尚未初始化的字段。如果您希望等效行为绝不是错误,请参阅以下内容(可以看到运行here):
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at Example.next(Example.java:11)
at Example.<clinit>(Example.java:7)
可以看出输出如下。
{{1}}
答案 1 :(得分:0)
我想你会发现问题发生在这里
Thread.currentThread().getStackTrace()[3].getClassName()
您可能需要做更像
的事情StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
String className = stackTrace[Math.min(3, stackTrace.length - 1)].getClassName();
或类似:P