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

时间:2015-01-15 23:06:13

标签: java classloader

如果这个问题的答案很简单,我会提前道歉。我似乎对Java中的类加载知之甚少。

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

问题:

如果外部JAR文件尝试使用getClass().getClassLoader().getResourceAsStream("properties")打开该文件,为什么不从我的应用程序加载该文件。不是我想要它,但在这种情况下ClassLoader不会是加载我的应用程序的那个吗?我认为该方法将使用绝对路径来查找资源。外部JAR中的类是否加载了不同的类加载器?

3 个答案:

答案 0 :(得分:2)

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

有关官方解释,请参阅http://docs.oracle.com/javase/tutorial/ext/basics/load.html

这是第一个实际的类加载器,它拥有获胜的资源。如果类加载器没有其资源,请再次使用父级。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

它依赖于此实现它返回的内容,如果URLClassLoader这将是URLClassPath.findResource(),它将遍历所有加载器(每个搜索路径条目一个加载器)并返回第一个查找。

在正常的应用程序中,JAR和所有库都由相同的(Application)类加载器加载。如果是太阳发射器,则sun.misc.Launcher$AppClassLoader延伸URLClassLoader。它将类路径中的所有JAR和类放在搜索列表中。

最好将资源设置为唯一(将它们放入包中)或检索所有资源并选择正确的资源(或全部)。后者例如在ServiceLoader找到给定服务的所有实现时使用。