Class#getResource(String name)和Class#getResourceAsStream(String name)分别比ClassLoader#getResource(String name)和ClassLoader#getResourceAsStream(String name)只多了一步,就是搜索之前先进行资源名称的预处理resolveName(name)
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;
}
逻辑相对比较简单:
1、如果资源名称以'/'开头,那么直接去掉'/',这个时候的资源查找实际上退化为ClassPath中的资源查找。
2、如果资源名称不以'/'开头,那么解析出当前类的实际类型(因为当前类有可能是数组),取出类型的包路径,替换包路径中的'.'为'/',再拼接原来的资源名称。举个例子:"club.throwable.Main.class"中调用了Main.class.getResource("doge.jpg"),那么这个调用的处理资源名称的结果就是club/throwable/doge.jpg。
System.out.println(ConvertTool.class.getResource(""));
System.out.println(ConvertTool.class.getResource("/"));
System.out.println(ConvertTool.class.getClassLoader().getResource(""));
System.out.println(ConvertTool.class.getClassLoader().getResource("/"));
file:/E:/code/java/callback/converttool/target/classes/com/ecarx/converttool/
file:/E:/code/java/callback/converttool/target/classes/
file:/E:/code/java/callback/converttool/target/classes/
null
网友评论