其实就是加载文件所在路径地址
文件目录结构:
测试代码:
public class TestManin {
public static void main(String[] args) {
// 当前类(class)所在的包目录
System.out.println("TestManin.class.getResource(\"\") = " + TestManin.class.getResource("")); // 展示的是当前文件从跟路径到当前文件的包的路径
System.out.println("TestManin.class.getClassLoader().getResource(\"\") = " + TestManin.class.getClassLoader().getResource("")); // class 和 classloader 是一样的
// class path根目录
System.out.println("TestManin.class.getResource(\"/\") = " + TestManin.class.getResource("/"));
System.out.println("TestManin.class.getClassLoader().getResource(\"/\") = " + TestManin.class.getClassLoader().getResource("/")); //classloader不能加"/" // 仅限根路径
System.out.println("____________________________________");
// TestManin.class在<bin>/testpackage包中
// 2.properties 在<bin>/testpackage包中
System.out.println("TestManin.class.getResource(\"1.properties\") = " + TestManin.class.getResource("1.properties")); //
System.out.println("TestManin.class.getResource(\"subpackage/123.txt\") = " + TestManin.class.getResource("subpackage/123.txt"));
System.out.println("TestManin.class.getResource(\"/1.properties\") = " + TestManin.class.getResource("/1.properties"));
System.out.println("TestManin.class.getClassLoader().getResource(\"1.properties\") = " + TestManin.class.getClassLoader().getResource("1.properties"));
System.out.println("TestManin.class.getClassLoader().getResource(\"/1.properties\") = " + TestManin.class.getClassLoader().getResource("/1.properties"));
System.out.println("____________________________________");
// TestManin.class在<bin>/testpackage包中
// 3.properties 在<bin>/testpackage.subpackage包中
System.out.println("TestManin.class.getResource(\"subpackage/3.properties\") = " + TestManin.class.getResource("subpackage/3.properties"));
// TestManin.class在<bin>/testpackage包中
// 1.properties 在bin目录(class根目录)
System.out.println("TestManin.class.getResource(\"/1.properties\") = " + TestManin.class.getResource("/1.properties"));
}
}
输出结果:
TestManin.class.getResource("") = file:/F:/testSpace/testProject/out/production/testProject/testpackge/
TestManin.class.getClassLoader().getResource("") = file:/F:/testSpace/testProject/out/production/testProject/
TestManin.class.getResource("/") = file:/F:/testSpace/testProject/out/production/testProject/
TestManin.class.getClassLoader().getResource("/") = null
____________________________________
TestManin.class.getResource("1.properties") = null
TestManin.class.getResource("subpackage/123.txt") = file:/F:/testSpace/testProject/out/production/testProject/testpackge/subpackage/123.txt
TestManin.class.getResource("/1.properties") = file:/F:/testSpace/testProject/out/production/testProject/1.properties
TestManin.class.getClassLoader().getResource("1.properties") = file:/F:/testSpace/testProject/out/production/testProject/1.properties
TestManin.class.getClassLoader().getResource("/1.properties") = null
____________________________________
TestManin.class.getResource("subpackage/3.properties") = file:/F:/testSpace/testProject/out/production/testProject/testpackge/subpackage/3.properties
TestManin.class.getResource("/1.properties") = file:/F:/testSpace/testProject/out/production/testProject/1.properties
Process finished with exit code 0
*.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);
}
*.getClassLoader().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
最终调用的是ClassLoader 类的getResource方法。只不过Class.getResource是先调用Class 的 getResource 方 法,在这个getResource 方法中,再去调用ClassLoader 类的getResource方法
那么Class类中的getResource方法做了什么呢,主要的一句是 name = resolveName(name);
测试:
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) { // 对于不以/开头的文件,
Class<?> c = this; //获取当前加载类的完整的类路径,我这里是class testpackge.TestManin
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;
}
calss加"/"和classloader一样是项目根路径,后续想要什么文件一级一级往下写就行
TestManin.class.getResource("") = file:/F:/testSpace/testProject/out/production/testProject/testpackge/
TestManin.class.getClassLoader().getResource("") = file:/F:/testSpace/testProject/out/production/testProject/
TestManin.class.getResource("/") = file:/F:/testSpace/testProject/out/production/testProject/
TestManin.class.getClassLoader().getResource("/") = null