NoClassDefFoundError和静态vs实例级别

时间:2013-10-02 18:34:50

标签: java static

假设我运行以下代码

import java.util.ArrayList;
import java.util.List;

public class NoClassDefFoundErrorDueToStaticInitFailure {

    public static void main(String args[]) {
        System.out.println("Main start");
        new User("1");
    }
}

class User {
    private static String USER_ID = getUserId();

    public User(String id) {
        this.USER_ID = id;
    }

    private static String getUserId() {
        throw new RuntimeException("UserId Not found");
    }

}

它给出了

Main start
Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.NoClassDefFoundError.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:10)
Caused by: java.lang.RuntimeException: UserId Not found
    at com.NoClassDefFoundError.User.getUserId(NoClassDefFoundErrorDueToStaticInitFailure.java:22)
    at com.NoClassDefFoundError.User.<clinit>(NoClassDefFoundErrorDueToStaticInitFailure.java:15)
    ... 1 more

但是,如果我从上面的User类中删除静态并使其如下所示

class User {
    private String USER_ID = getUserId();

    public User(String id) {
        this.USER_ID = id;
    }

    private String getUserId() {
        throw new RuntimeException("UserId Not found");
    }
}
现在

堆栈跟踪是:

Main start
Exception in thread "main" java.lang.RuntimeException: UserId Not found
    at com.NoClassDefFoundError.User.getUserId(NoClassDefFoundErrorDueToStaticInitFailure.java:22)
    at com.NoClassDefFoundError.User.<init>(NoClassDefFoundErrorDueToStaticInitFailure.java:15)
    at com.NoClassDefFoundError.NoClassDefFoundErrorDueToStaticInitFailure.main(NoClassDefFoundErrorDueToStaticInitFailure.java:10)

由于删除了静态(类级别)关键字

,无法理解为何发生此更改

1 个答案:

答案 0 :(得分:2)

在第一个示例中,当您到达

行时
new User("1");

加载并初始化User类,执行

private static String USER_ID = getUserId();
由于ExceptionInInitializerError中出现RuntimeException

getUserId()而失败。 ExceptionInInitializerError抛出ClassLoader

在第二个示例中,您只需要一个抛出RuntimeException的实例方法。当你最终调用该方法时,它将冒泡到JVM的未捕获异常处理程序并终止该程序。


考虑阅读When Initialization Occurs的Java语言规范章节。