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

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

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

那么当true或false传递给resolve参数时?
我对这两个function感到很困惑。

谢谢。

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

这可能很有用,例如,如果您想加载一个可能格式错误的新类,并且不希望JVM在类错误的情况下抛出validation错误。

该类在首次使用时(或至少使用过的部分)仍然是链接的 – 使用resolve标志可以使VM立即执行此链接(并抛出相关错误)而不是以后。

你可以尝试一下。

 public class Test3 { static{ new Test(); } } 

编译之后,将Test Class从具体类更改为interface.but仍然是Test3链接到具体的Class Test.Then如果resolve为false,JVM将不会发现此错误。这非常有趣。 实际上, Class someClass1= Class.forName("Test3",false,cls)也不会解析Test3。这意味着不会抛出任何错误。

但是如果在subClass或Class.forName("Test3")设置resolve true,那么运行时中的JVM将发现类链接错误。

 Exception in thread "main" java.lang.InstantiationError: Test at Test3.(Test3.java:6) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) 

供您参考,Java语言规范 – 12.3类和接口的链接解释了resolveClass的作用。

12.3 类和接口的链接链接是获取类或接口类型的二进制forms并将其组合到Java虚拟机的运行时状态的过程,以便可以执行它。 始终在链接之前加载类或接口类型。 链接涉及三种不同的活动: 符号引用的validation,准备和解决 。链接的精确语义在Java虚拟机规范第二版的第5章中给出。 在这里,我们从Java编程语言的角度概述了该过程。

12.3.3符号引用解析类或接口的二进制表示使用其他类和接口(第13.1节)的二进制名称(第13.1节),以符号方式引用其他类和接口及其字段,方法和构造函数。 对于字段和方法,这些符号引用包括声明字段或方法的类或接口类型的名称,以及字段或方法本身的名称以及相应的类型信息。 在可以使用符号引用之前,它必须经历分辨率,其中检查符号引用是正确的,并且通常用直接引用替换,如果重复使用引用,则可以更有效地处理该引用。

如果在解析期间发生错误,则会引发错误。 最典型的情况是,这将是IncompatibleClassChangeError类的以下子类之一的实例,但它也可能是IncompatibleClassChangeError的某个其他子类的实例,甚至是IncompatibleClassChangeError类本身的实例。 在程序中直接或间接使用对类型的符号引用的任何一点都可能抛出此错误:

IllegalAccessError :遇到符号引用,指定字段的使用或赋值,或方法的调用,或类的实例的创建,包含引用的代码无法访问该类,因为该字段或方法是声明私有,受保护或默认访问(非公开),或者因为该类未声明为public。 例如,如果最初声明为public的字段在引用该字段的另一个类已经编译后被更改为私有(第13.4.6节),则会发生这种情况。

InstantiationError :遇到了在类实例创建表达式中使用的符号引用,但是无法创建实例,因为引用结果是引用接口或抽象类。 例如,如果在编译了引用相关类的另一个类(第13.4.1节)之后,最初不是抽象的类被更改为抽象,则会发生这种情况。

NoSuchFieldError :遇到了一个符号引用,它引用了特定类或接口的特定字段,但该类或接口不包含该名称的字段。 例如,如果在编译引用该字段的另一个类(第13.4.7节)之后从类中删除了字段声明,则会发生这种情况。

NoSuchMethodError :遇到符号引用,它引用特定类或接口的特定方法,但类或接口不包含该签名的方法。 例如,如果在编译引用该方法的另一个类(第13.4.11节)之后从类中删除了方法声明,则会发生这种情况。 此外,如果类声明了无法找到实现的本机方法,则可能抛出UnsatisfiedLinkErrorLinkageError的子 )。 如果使用该方法或更早,则会发生错误,具体取决于虚拟机使用的解析策略类型(第12.3节)。