如果无法解析导入语句会发生什么?

时间:2012-09-26 07:19:08

标签: java class jvm classloader

我不清楚以下内容:
JVM在需要时加载一个类,比如延迟初始化,对吧? 现在,如果类A执行importB哪个类B实际上不在文件系统中(例如B.class已删除或未传递或任何原因)
那么类A是否会被加载并运行如果没有调用类B的方法?
由于导入无法解决,A根本无法运行?
A已加载并运行到某一点?

2 个答案:

答案 0 :(得分:7)

import语句仅对编译器很重要。在字节码中,对其他类的所有引用都是完全限定的。这就是为什么超级进口在运行时无关紧要的原因。

在您的情况下,JVM将尝试加载加载和验证A 所需的所有类,因此它将尝试立即加载B ,但依赖类是只在需要时懒洋洋地加载。请查看以下示例:

public class A {

    public static void bar() {
        new B().foo();
    }

    public static void main(String[] args) {
        //bar();
    }

}

编译A.java并删除B.class。如果不调用bar()方法,您的程序就可以正常运行。但是一旦你实际使用B类取消注释代码,你就会变得讨厌:

Exception in thread "main" java.lang.NoClassDefFoundError: B
    at A.bar(A.java:4)
    at A.main(A.java:8)
Caused by: java.lang.ClassNotFoundException: B
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    ... 2 more

如果B不可用,您将获得NoClassDefFound或类似内容。

答案 1 :(得分:0)

如果A.class需要缺少B.class。无法加载A.class。

加载类是recursion operation

当A.class需要B.class时,JVM会在PermGen中搜索B.class。如果加载B.class并存储在PermGen中,JVM将not reload B.class但直接从PermGen获取它,否则JVM将递归加载B.class。

当JVM找不到B.class时,它会抛出NoClassDefFoundError

See more about NoClassDefFoundError in [Java Specification] :page 319