Java程序中,通常通过getResource()方法获取资源,其中有一下方法及其区别
Class.getResource(String path);
/*
path不以"/"开头时,默认是此包下获取资源
path在以"/"开头时,默认是此项目的ClassPath根下获取资源
*/
package com.test.testResource;
public class Main {
public static void main(String[] args) {
System.out.println(Main.class.getResource("/"));
}
}
/*
输出为file:/C:/Users/Chywan/OneDrive/daily_program/Java/LearningCode/Test/target/classes/
*/
package com.test.testResource;
public class Main {
public static void main(String[] args) {
System.out.println(Main.class.getResource(""));
}
}
/*
输出为file:/C:/Users/Chywan/OneDrive/daily_program/Java/LearningCode/Test/target/classes/com/test/testResource/
*/
//所以,其实在没有加入"/“时获取的是相对于类的相对路径为”“所对应的绝对路径,在使用”/“后获取的是编译后的类的路径,如maven编译的项目就是target/classes/
Class.getClassloader.getResource();
/*
ClassLoader的加载是双亲委派机制,所以在获取Main.class.getClassLoader()时获得的是BootstrapClassLoader,是C++底层实现的,所以getResource("/")获取的是null,而getResource("")时,获取的是加载器的相对路径,我的理解是加载器是从项目的类根路径起效的,所以就算类根路径
*/
package com.test.testResource;
public class Main {
public static void main(String[] args) {
System.out.println(Main.class.getClassLoader().getResource("/"));
}
}
/*输出为null
*/
package com.test.testResource;
public class Main {
public static void main(String[] args) {
System.out.println(Main.class.getClassLoader().getResource(""));
}
}
/*输出为file:/C:/Users/Chywan/OneDrive/daily_program/Java/LearningCode/Test/target/classes/
*/
// 源码里面可以看到resolveName()方法对路径进行处理,本质Class.getResource(String path)还是调用了ClassLoader的方法。
public URL getResource(String name) {
name = resolveName(name);
//获取资源
}
private String resolveName(String name) {
if (!name.startsWith("/")) { //相对路径
Class> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getPackageName(); //获取包名
if (baseName != null && !baseName.isEmpty()) { //拼接路径
name = baseName.replace('.', '/') + "/" + name;
}
} else { //根路径开始
name = name.substring(1);
}
return name;
}