首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java类加载器层次结构中,两个类加载器(假设两个类加载器都是URLClassLoader)如何加载类?

在java类加载器层次结构中,两个类加载器(假设两个类加载器都是URLClassLoader)如何加载类?
EN

Stack Overflow用户
提问于 2019-05-10 04:13:16
回答 1查看 445关注 0票数 0

最近,我开始学习如何在Java中精确地使用类加载器。以下是我所观察到的3点:

点-1:每个类装入器都有一个父类装入器。当类加载器被要求加载类或资源时,它会在尝试加载项本身之前咨询它的父类加载程序。父母反过来咨询其父母,依此类推。因此,只有在所有祖先类加载器都找不到当前类加载器参与的项之后。

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

Point-3:子类装入器可以检查父类加载器的缓存,但是父类加载器看不到子类加载的类。

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

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

问题1: url1类加载器已经从位置x/abc.jar加载了一个类A.class。同样,url2希望从同一个位置加载相同的类。url2是新加载还是将使用url1加载的相同的加载?我试着检查,只有一次静态块被执行,所以被欺骗的类只被游荡了一次。根据我的理解,第1点和第3点都不令人满意。

问题2:做url2类加载器可以检查url1类加载器的缓存。与第三点有关。

EN

回答 1

Stack Overflow用户

发布于 2019-05-10 04:58:02

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

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

代码语言:javascript
复制
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));
}

输出

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56070608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档