当我在类加载上做一些实验时,我编写了如下的简单代码。
CustomClass customClass1 = new CustomClass();
CustomClass customClass2 = new CustomClass();
并注意到,对于第一个实例创建,它转到loadClass方法并调用findLoadedClass方法(如果它已由当前加载器加载)。事情并非如此,它已经开始上课了。 但对于第二个实例,它没有转到loadClass方法并直接创建了该实例。
所以我的问题是,当它创建第二个实例时,它已经是新的,已经加载了类,所以它没有转到loadClass方法。所以当jvm现在已经加载哪个类而哪个没有加载那么需要在loadClass方法中调用findLoadedClass方法。
答案 0 :(得分:1)
从Java虚拟机规范(适用于Java 8),第5.3.2节:
以下步骤用于加载,从而使用用户定义的类加载器L创建由N表示的非阵列类或接口C.
首先,Java虚拟机确定L是否已被记录为由N表示的类或接口的初始加载器。如果是,则此类或接口为C,并且不需要创建类。
否则,Java虚拟机在L上调用loadClass(N)。调用返回的值是创建的类或接口C.然后Java虚拟机记录L是C的启动加载器(§5.3.4) )。
这解释了为什么在您的示例中不再调用loadClass
。但这并不意味着永远不会在这个特定类'fqn的特定类加载器上调用loadClass
。例如,由于类加载委托,当一些其他类加载器充当启动类加载器时,可能会发生这种情况,但是将对loadClass
的调用委托给此类加载器的loadClass
。因此呼叫findLoadedClass
。