getResource/getResourceAstream
示例
package com.lh.st.classloader;
public class ClassLoaderLearn {
public static void main(String[] args) {
//file:/Users/lh/java_st/java-base/target/classes/
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
//null
System.out.println(Thread.currentThread().getContextClassLoader().getResource("/"));
//file:/Users/lh/java_st/java-base/target/classes/
System.out.println(ClassLoaderLearn.class.getClassLoader().getResource(""));
//null
System.out.println(ClassLoaderLearn.class.getClassLoader().getResource("/"));
//file:/Users/lh/dp_arch/Log4jLearning/target/classes/com/lh/classloader/
System.out.println(ClassLoaderLearn.class.getResource(""));
//file:/Users/lh/dp_arch/Log4jLearning/target/classes/
System.out.println(ClassLoaderLearn.class.getResource("/"));
//com.lh.st.classloader.ClassLoaderLearn
System.out.println(ClassLoaderLearn.class.getName());
System.out.println(ClassLoaderLearn.class.getResource("/com/lh/st/classloader/"));
//file:/Users/lh/java_st/java-base/target/classes/com/lh/st/classloader/ClassLoaderLearn.class
System.out.println(ClassLoaderLearn.class.getResource("ClassLoaderLearn.class"));
}
}
Class的getResource和getResourceAsstream方法最终还是调用ClassLoader的getResource和getResourceAsstream方法。
总结
Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从
ClassPath根下获取。Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由
ClassLoader获取资源。
Class 的getResource 和 getReourceAsStream
getResource()
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
//还是调用的ClassLoader的getResource
return cl.getResource(name);
}
Class的getResource()最终还是调用的ClassLoader的getReource().首先找到类加载器,如果类加载器是null,说明是根加载器,调用ClassLoader.getSystemResource(name)
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;
}
如果以/
开头,返回/
后面的字符串。如果不是以/
开头,返回 (当前包路径+name)
getResourceAsstream()
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
和getResource一样,最终也是调用ClassLoader的getResourceAsstream方法
ClassLoader的 getResource 和 getResourceAsstream
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;
}
首先父加载器中查找,然后根加载器中查找,如果没有,则返回null
getResourceAstream()
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
try {
return url != null ? url.openStream() : null;
} catch (IOException e) {
return null;
}
}
调用getResource
方法得到URL,然后获取打开资源的流