类加载器资源路径总是绝对的?

问题描述 投票:0回答:1

在关于类加载方法之间的差异的流行答案中,Jon Skeet 指出,

类加载器资源路径始终被视为绝对路径。

一个更流行的答案用一个例子证实了这一说法。

ClassLoader.getResourceAsStream(path)
将考虑所有路径 绝对路径。所以打电话
String.getClassLoader().getResourceAsString("myfile.txt")
String.getClassLoader().getResourceAsString("/myfile.txt")
两者都会 在类路径中的以下位置查找文件:
./myfile.txt

忽略该示例无法编译的事实,共识表明前导斜杠与类加载器无关。

一个简单的测试表明情况并非如此。

Foo.class.getClassLoader().getResource("test.xml")  // file

Foo.class.getClassLoader().getResource("/test.xml")  // null

我只是将路径

files/test.xml
添加到测试项目的类路径中,其中一个名为
Foo
的类包含一个
main()
方法,打印出这两个调用的结果。既然数百人已经对上述答案进行了投票,我错过了什么?类加载器是绝对的还是依赖于输入名称的结构?


这篇Oracle 博客文章对我的理解很有帮助。

最终根据资源名称构造 URL 的方法是 URLClassPath.JarLoader.checkResource().

java classloader
1个回答
1
投票

显然不是。

由类加载器来解释

name
中的
getResource(name)

检查

URLClassLoader
的源码,最终调用了

new URL(baseURL, name)

这里重要的是

name
是绝对的还是相对的

对于某些

baseURL
,绝对
/foo/bar
和相对
foo/bar
可能具有相同的效果。特别是,类路径中的“jar 文件 URL” 始终是这种情况

baseURL:       jar:file:/home/duke/duke.jar!/

 foo/bar  ->   jar:file:/home/duke/duke.jar!/foo/bar 
/foo/bar  ->   jar:file:/home/duke/duke.jar!/foo/bar 
© www.soinside.com 2019 - 2024. All rights reserved.