今天在写代码的时候遇到了一个坑,内容如标题,特此记录一下,废话不多说,先看代码。
首先看看Class.getResource方法:
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
请注意:在方法的第一行有一个resolveName方法,这个方法就是class.getResource和classLoader.getResource的区别。
ClassLoader.getResource方法:
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}
这也说明了Class.getResource获取资源默认是相对路径,如果要获取根目录资源则资源名称需要“/”打头,而ClassLoader.getResource获取的就是根路径资源,原因就是因为Class.resolveName方法是这样写的:
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class<?> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}
可见如果我们要加载录资源文件使用Class.getResource的话,他会将根路径中"/"处理一下然后,然后交给ClassLoader去加载。
总结的结论:
1. Class.getResource方法加载的资源文件路径为相对路径,如果要加载根路径资源需要以"/" 打头。
2. ClassLoader.getResource方法加载的资源文件路径为根路径,不能使用相对路径加载资源文件,所以如果要加载根路径资源,资源名称不能以“/”打头。