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