我只是不明白为什么使用ClassLoader会导致这两种情况的行为有所不同。有人可以解释ClassLoader如何/为什么更改搜索,以使其需要进入jar的完整路径?
package com.example;
import java.io.InputStream;
public class SomeClass {
private static InputStream stm;
static {
for (final String s : new String[] { "file.png", "com/example/file.png", "/com/example/file.png" }) {
// case 1 - w/o classLoader
stm = SomeClass.class.getResourceAsStream(s);
System.out.println("w/o : " + (stm == null ? "FAILED to load" : "loaded") + " " + s);
// case 2 - w/ classLoader
stm = SomeClass.class.getClassLoader().getResourceAsStream(s);
System.out.println("w/classloader: " + (stm == null ? "FAILED to load" : "loaded") + " " + s);
}
}
public static void main(final String args[]) {}
}
产生:
w/o : loaded file.png
w/classloader: FAILED to load file.png
w/o : FAILED to load com/example/file.png
w/classloader: loaded com/example/file.png
w/o : loaded /com/example/file.png
w/classloader: FAILED to load /com/example/file.png
最佳答案
因为根据调用的getResourceAsStream()
方法,路径的评估方式不同。
如果在类Class.getResourceAsStream()
上调用com.example.SomeClass
,则如果路径不是以SomeClass
开头,则相对于/
评估路径,因此file.png
变为/com/example/file.png
,而com/example/file.png
变为/com/example/com/example/file.png
。
如果在其ClassLoader.getResourceAsStream()
上调用ClassLoader
,则该路径是隐式绝对的,并且不能以/
开头,因此file.png
变为/file.png
,而com/example/file.png
变为/com/example/file.png
。
如果使用类似/com/example/file.png
的绝对路径,则必须使用Class
方法。
不幸的是,ClassLoader.getResourceAsStream()
的这种隐式绝对性仅隐式地记录在Class.getResourceAsStream()
的文档中,该文档指出,在将其委托给ClassLoader
的方法之前,它会删除斜杠。
关于java - 加载.jar资源时使用ClassLoader,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37234018/