gpt4 book ai didi

java - 为什么findLoadedClass方法调用返回不同的结果?

转载 作者:太空宇宙 更新时间:2023-11-04 09:29:37 26 4
gpt4 key购买 nike

考虑自定义类加载器class CustomClassLoader extends ClassLoader{}

如果我按如下方式调用loadClass

ClassLoader loader = new ClassLoader(){}; 
loader.loadClass("java.util.ArrayList");
Method method = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
method.setAccessible(true);
System.out.println(method.invoke(loader,"java.util.ArrayList"));

它输出null

但是如果我更换

loader.loadClass("java.util.ArrayList"); 

Class.forName("java.util.ArrayList",true,loader);

它输出class java.util.ArrayList

谁能解释一下这个问题吗?

最佳答案

默认的ClassLoader实现按以下顺序执行类加载:

  1. Invoke findLoadedClass(String) to check if the class has already been loaded.
  2. Invoke the loadClass method on the parent class loader. If the parent is null the class loader built-in to the virtual machine is used, instead.
  3. Invoke the findClass(String) method to find the class.

这是直接摘自 Javadoc .

当您调用 loadClass 时,您的实现将委托(delegate)给父类加载器,然后再尝试加载它本身。这恰好是您的系统类加载器。

在这种情况下,您的类已经位于系统 ClassLoader 的类路径中,因此它已被加载。

当您稍后调用 findLoadedClass 时,该方法仅检查指定的 ClassLoader 是否已加载该类。它不再执行进一步的委派。

当您调用 method.invoke(loader, "java.util.ArrayList") 时,您会尝试在 CustomerClassLoader 中查找已加载的类。这会失败,因为是父类加载器执行了加载。

您可以通过调用系统类加载器上的方法来证明这一点,如下所示:

method.invoke(ClassLoader.getSystemClassLoader(),"java.util.ArrayList")

关于java - 为什么findLoadedClass方法调用返回不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57253634/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com