为什么NoClassDefFoundError由静态字段初始化失败引起?
|
这是一个有趣的Java问题。
以下简单的Java程序包含由方法静态初始化的静态字段。实际上,我强迫计算intiailize值的方法引发NullPointException,当我访问这样的静态字段时,将引发NoClassDefFoundError。看来VM对待Class不完整。
但是当我访问该类时,它仍然可用;
有谁知道为什么?
class TestClass {
public static TestClass instance = init();
public static TestClass init() {
String a = null;
a.charAt(0); //force a null point exception;
return new TestClass();
}
}
class MainClass {
static public void main(String[] args) {
accessStatic(); // a ExceptionInInitializerError raised cause by NullPointer
accessStatic(); //now a NoClassDefFoundError occurs;
// But the class of TestClass is still available; why?
System.out.println(\"TestClass.class=\" + TestClass.class);
}
static void accessStatic() {
TestClass a;
try {
a = TestClass.instance;
} catch(Throwable e) {
e.printStackTrace();
}
}
}
没有找到相关结果
已邀请:
4 个回复
疮痪徘弦漏
。如果Class对象处于错误状态,则无法进行初始化。释放对Class对象的锁定,并引发NoClassDefFoundError。 6-8继续初始化,8执行初始化程序,通常发生在步骤9中:
。如果初始化程序的执行正常完成,则锁定此Class对象,将其标记为完全初始化,通知所有等待的线程,释放锁,然后正常完成此过程。 但是我们在初始化器中出现了一个错误,因此:
否则,初始化器必须通过抛出一些异常E来突然完成。如果E的类不是Error或其子类之一,则以E作为参数创建ExceptionInInitializerError类的新实例,并在适当的位置使用此对象E在接下来的步骤中。但是,如果由于发生OutOfMemoryError而无法创建ExceptionInInitializerError的新实例,请在后续步骤中使用OutOfMemoryError对象代替E。 是的,我们看到了空指针异常的4/5 b / c。
。锁定Class对象,将其标记为错误,通知所有正在等待的线程,释放锁定,并以原因E或其上一步中所述的替换突然结束此过程。 (由于某些早期实现中的缺陷,类初始化期间的异常被忽略,而不是引起此处所述的ExceptionInInitializerError。) 然后将该类标记为错误,这就是为什么我们第二次从步骤5中获得异常。 令人惊讶的部分是第三份打印输出,显示出
中的
实际上持有对物理
对象的引用。 可能是因为ѭ9仍然存在,所以它被标记为错误。它已经被加载和验证。
犀寺扦
辽躺
娠频摩