gpt4 book ai didi

java - java Class-loader loader Hierarchy 中同一级别的两个类加载器(假设都是 URLClassLoader)如何加载一个类

转载 作者:行者123 更新时间:2023-12-02 05:48:46 24 4
gpt4 key购买 nike

最近我开始学习类加载器在 Java 中到底是如何工作的。以下是我观察到的三点:

第一点:每个类加载器都有一个父类加载器。当类加载器被要求加载类或资源时,它会在尝试加载项目本身之前咨询其父类加载器。父级又咨询其父级,依此类推。所以只有在所有祖先类加载器都找不到该项之后,当前类加载器才会介入。

Point-2:由两个加载器加载的同一个类被视为两个不同的类实体。我们甚至不能将一个类(loader 1)对象转换为另一个类(由loader2加载)。它将抛出 ClassCastException。

第三点:子类加载器可以检查父类加载器的缓存,但父类加载器看不到已加载的类 由 child 。

基于以上几点我有两个问题:

情况:我在同一个应用程序中创建了一个 URLClassloader 对象 url1 和另一个 URLClassloader 对象 url2。正如我们所知,默认情况下两个类加载器将具有相同的父类加载器。假设这里的父类加载器是SystemClassLoader。

问题 1: url1 类加载器已从位置 x/abc.jar 加载类 A.class。 url2 再次想要从同一个加载相同的类 地点。 url2 会重新加载还是会使用 url1 加载的相同内容?我尝试检查,只有一次静态 block 被执行,所以相信类只被加载一次。据我了解,这不满足Point-1和Point-3。

问题2:url2类加载器是否可以检查url1类加载器的缓存。与第 3 点相关。

最佳答案

类加载器是完全独立的,因此您可以获得两个不同的类。

由于您没有发布 MCVE (最小、完整和可验证的示例),这是一个使用任意选择的 .jar 文件的示例。

public static void main(String[] args) throws Exception {
String jarFile = "/path/to/commons-lang3-3.8.1.jar";

URLClassLoader url1 = new URLClassLoader(new URL[] { new File(jarFile).toURI().toURL() });
URLClassLoader url2 = new URLClassLoader(new URL[] { new File(jarFile).toURI().toURL() });

Class<?> fractionClass1 = url1.loadClass("org.apache.commons.lang3.math.Fraction");
Class<?> fractionClass2 = url2.loadClass("org.apache.commons.lang3.math.Fraction");

Object oneHalf1 = fractionClass1.getField("ONE_HALF").get(null);
Object oneHalf2 = fractionClass2.getField("ONE_HALF").get(null);

System.out.println("url1 = " + url1);
System.out.println("url2 = " + url2);
System.out.println(" Same? " + (url1 == url2));
System.out.println("fractionClass1 = " + fractionClass1);
System.out.println("fractionClass2 = " + fractionClass2);
System.out.println(" Same? " + (fractionClass1 == fractionClass2));
System.out.println("oneHalf1 = " + oneHalf1);
System.out.println("oneHalf2 = " + oneHalf2);
System.out.println(" Same? " + (oneHalf1 == oneHalf2));
}

输出

url1 = java.net.URLClassLoader@1e81f4dc
url2 = java.net.URLClassLoader@4d591d15
Same? false
fractionClass1 = class org.apache.commons.lang3.math.Fraction
fractionClass2 = class org.apache.commons.lang3.math.Fraction
Same? false
oneHalf1 = 1/2
oneHalf2 = 1/2
Same? false

关于java - java Class-loader loader Hierarchy 中同一级别的两个类加载器(假设都是 URLClassLoader)如何加载一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56070608/

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