如果存在重复项,Java中的类加载器如何知道加载哪个文件资源?

如果存在重复项,Java中的类加载器如何知道加载哪个文件资源?,java,classloader,Java,Classloader,如果这个问题的答案很简单,我提前道歉。我似乎对Java中的类加载没有足够的了解 假设我的应用程序中有一个名为“属性”的文件。我的应用程序使用一个外部JAR,在这个JAR中还有一个名为“properties”的文件 问题: 如果外部JAR文件试图用getClass().getClassLoader().getResourceAsStream(“属性”)打开该文件,为什么不从我的应用程序加载该文件。我并不希望它这样做,但在这种情况下,类加载器不是加载我的应用程序的那个吗?我认为该方法将使用绝对路径来

如果这个问题的答案很简单,我提前道歉。我似乎对Java中的类加载没有足够的了解

假设我的应用程序中有一个名为“属性”的文件。我的应用程序使用一个外部JAR,在这个JAR中还有一个名为“properties”的文件

问题:


如果外部JAR文件试图用
getClass().getClassLoader().getResourceAsStream(“属性”)
打开该文件,为什么不从我的应用程序加载该文件。我并不希望它这样做,但在这种情况下,类加载器不是加载我的应用程序的那个吗?我认为该方法将使用绝对路径来查找资源。外部JAR中的类是否使用不同的类加载器加载?

否,它加载在该类的类加载器中找到的第一个类。如果要使用绝对路径打开文件,请打开指向该文件的
InputStream
。 外部JAR中的类可能使用不同的类加载器(例如,在Java EE容器中)加载,但需要将类加载器链接起来,以便查看它们。

Th
ClassLoader\getResourceAsStream(String)
调用
getResource(String)
并将其作为父级上的getResource()。如果没有找到任何内容,那么它将询问类加载器
findResource(String)

它取决于此实现返回的内容,在
URLClassLoader
的情况下,它将遍历所有加载程序(每个搜索路径条目一个加载程序)并返回第一个查找

在普通应用程序中,JAR以及所有库都由同一(应用程序)类加载器加载。对于Sun launcher,这是扩展了
URLClassLoader
Sun.misc.launcher$AppClassLoader
。它将类路径中的所有JAR和类放在搜索列表中


让资源成为唯一的(将它们放在包中)或检索所有资源并选择正确的一个(或全部)是一个好主意。例如,ServiceLoader在查找给定服务的所有实现时使用后者。

类和资源的类加载机制是相同的(但找到的字节处理方式不同)

有关官方解释,请参见

它是实际询问的第一个类加载器,其中有获胜的资源。如果类加载器没有资源,请与父类一起重试


(请注意,对于web应用程序-WAR文件-这与首先询问哪个文件略有不同)。

当您说“第一个”时,您是指classloader找到的第一个吗?那么它真的可能是其中之一吗?@user3352357我在答案中添加了一些关于“第一个”的细节。