resource获取方法之一,java.lang.Class的getResource
可参考这两个:
http://stackoverflow.com/questions/3861989/preferred-way-of-loading-resources-in-java
主要说说this.getClass().getResource(String name),即JDK中java.lang.Class的方法public java.net.URL getResource(String name),返回一个URL对象。
有两种情况,看看这个例子:http://www.cnblogs.com/yejg1212/p/3270152.html
参数以’/’开头
从ClassPath根下获取,eclipse maven工程就是target/classes/或target/test-classes/
参数非’/’开头
从此类所在的package下取资源
如何实现的呢?
官方API:http://docs.oracle.com/javase/8/docs/api/index.html
Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the defining class loader of the class. This method delegates to this object’s class loader. If this object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResource(java.lang.String).
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a ‘/’ (‘\u002f’), then the absolute name of the resource is the portion of the name following the ‘/’.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with ‘/’ substituted for ‘.’ (‘\u002e’).
大致意思是:这个方法会将动作委托至这个对象的classLoader进行(还会涉及到这个classLoader 的parent classLoader),若不存在委托SystemClassLoader或者bootstrap class loader(应该涉及到双亲委派的内容)。主要说说参数,若以’/’开头则是相对于ClassPath的路径,不以’/’开头则是相对于该类文件所在位置路径,其原理是获取类全名,解析为该类所在位置相对于ClassPath的路劲,再拼接上入参。
看看源码
public java.net.URL getResource(String name) {
name = resolveName(name);//这一步会对参数进行解析,区分是否以'/'情况
ClassLoader cl = getClassLoader0();//获取这个对象的ClassLoader
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
private String resolveName(String name) {
if (name == null) {
return name;
}
//如果参数不以'/'开头
if (!name.startsWith("/")) {
Class<?> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
//获取该类的全名,去除类名,把点替换为路劲分隔符,再加上入参
//如 A.B.C.className --> A.B.C --> A/B/C --> A/B/C/name
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;
}
最后,调用该方法之后记得判空~~