loadClass(String name)和loadClass(String name, boolean resolve)的区别

7

loadClass(String name)loadClass(String name, boolean resolve)之间有什么区别?

我所知道的唯一区别是,如果resolve参数为true,则loadClass(String name, boolean resolve)会调用findLoadedClass(String)函数?

那么什么时候传递true或false到resolve参数?
我对这两个函数感到非常困惑。

谢谢。

3个回答

3

resolve参数控制是否链接已加载的类。在链接期间,静态常量将被初始化并分配内存。此外,还会验证类的正确性,并可能链接到其他类。

例如,如果您想加载一个可能存在格式错误的新类,并且不希望JVM在类存在错误时抛出验证错误,则可以使用此功能。


1

你可以试一试。

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编程语言的角度概述该过程。
12.3.3 符号引用的解析 类或接口的二进制表示引用其他类和接口及其字段、方法和构造函数,使用其他类和接口(§13.1)的二进制名称。对于字段和方法,这些符号引用包括声明字段或方法的类或接口类型的名称以及字段或方法本身的名称,以及适当的类型信息。在使用符号引用之前,必须进行解析,其中检查符号引用是否正确,并且通常会替换为直接引用,如果引用重复使用,则可以更有效地处理该引用。
如果在解析期间发生错误,则会抛出错误。最常见的情况是以下类的子类之一的实例IncompatibleClassChangeError,但也可能是IncompatibleClassChangeError的其他子类的实例,甚至是IncompatibleClassChangeError类的实例。此错误可能会在直接或间接使用类型的符号引用的程序中的任何点抛出: IllegalAccessError:遇到指定字段的使用或赋值、方法的调用或类的实例创建,但包含引用的代码没有访问权限,因为该字段或方法被声明为private、protected或默认访问(不是public),或者因为该类未声明为public。例如,如果最初声明为public的字段在引用该字段的另一个类编译后更改为private,则可能会发生这种情况(§13.4.6)。 InstantiationError:遇到用于类实例创建表达式的符号引用,但无法创建实例,因为引用结果是引用接口或抽象类。例如,如果最初不是抽象的类在引用该类的另一个类编译后更改为抽象,则可能会发生这种情况(§13.4.1)。 NoSuchFieldError:遇到引用特定类或接口的特定字段的符号引用,但该类或接口不包含该名称的字段。例如,如果从类中删除了字段声明,而其他引用该字段的类已经编译(§13.4.7),则可能会发生这种情况。 NoSuchMethodError:遇到引用特定类或接口的特定方法的符号引用,但该类或接口不包含该签名的方法。例如,如果从类中删除了方法声明,而其他引用该方法的类已经编译(§13.4.11)。此外,如果类声明了无法找到实现的本地方法,则可能会抛出UnsatisfiedLinkError(LinkageError的子类)。如果使用该方法或更早,则会发生错误,具体取决于虚拟机正在使用哪种解析策略(§12.3)。

1

当类被首次使用时(或至少是被使用的部分),它会被链接 - 使用 resolve 标志,您可以使虚拟机立即进行此链接(并抛出相关错误),而不是稍后再进行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接