loadClass(String name)
和loadClass(String name, boolean resolve)
之间有什么区别?
我所知道的唯一区别是,如果resolve
参数为true,则loadClass(String name, boolean resolve)
会调用findLoadedClass(String)函数?
那么什么时候传递true或false到resolve
参数?
我对这两个函数感到非常困惑。
谢谢。
loadClass(String name)
和loadClass(String name, boolean resolve)
之间有什么区别?
我所知道的唯一区别是,如果resolve
参数为true,则loadClass(String name, boolean resolve)
会调用findLoadedClass(String)函数?
那么什么时候传递true或false到resolve
参数?
我对这两个函数感到非常困惑。
谢谢。
resolve参数控制是否链接已加载的类。在链接期间,静态常量将被初始化并分配内存。此外,还会验证类的正确性,并可能链接到其他类。
例如,如果您想加载一个可能存在格式错误的新类,并且不希望JVM在类存在错误时抛出验证错误,则可以使用此功能。
你可以试一试。
public class Test3 {
static{
new Test();
}
}
编译后,将测试类从具体类更改为接口,但仍然将Test3链接到具体类Test。如果解决方案为false,则JVM将不会发现此错误。这非常有趣。实际上,Class someClass1= Class.forName("Test3",false,cls)
也不会解析Test3。这意味着不会抛出任何错误。
但是,如果在子类或Class.forName("Test3")
中设置resolve为true,则JVM在运行时将找到类链接错误。
Exception in thread "main" java.lang.InstantiationError: Test
at Test3.<clinit>(Test3.java:6)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
供您参考,Java语言规范 - 12.3 类和接口的链接 解释了resolveClass的作用。
12.3 类和接口的链接 链接是将类或接口类型的二进制形式合并到Java虚拟机的运行时状态中,以便可以执行它。在链接之前,必须先加载类或接口类型。链接涉及三个不同的活动:验证、准备和符号引用的解析。链接的精确语义在《Java虚拟机规范》第二版的第5章中给出。这里我们从Java编程语言的角度概述该过程。当类被首次使用时(或至少是被使用的部分),它会被链接 - 使用 resolve
标志,您可以使虚拟机立即进行此链接(并抛出相关错误),而不是稍后再进行。