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方法最終還是調(diào)用ClassLoader的getResource和getResourceAsstream方法阿浓。
總結(jié)
Class.getResourceAsStream(String path) : path 不以’/'開頭時(shí)默認(rèn)是從此類所在的包下取資源犀被,以’/'開頭則是從
ClassPath根下獲取。Class.getClassLoader.getResourceAsStream(String path) :默認(rèn)則是從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);
}
//還是調(diào)用的ClassLoader的getResource
return cl.getResource(name);
}
Class的getResource()最終還是調(diào)用的ClassLoader的getReource().首先找到類加載器,如果類加載器是null,說(shuō)明是根加載器,調(diào)用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;
}
如果以/
開頭,返回/
后面的字符串偏序。如果不是以/
開頭,返回 (當(dāng)前包路徑+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一樣,最終也是調(diào)用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;
}
}
調(diào)用getResource
方法得到URL题山,然后獲取打開資源的流