Java资源加载

19 浏览
0 Comments

Java资源加载

我想知道Class.getResource()ClassLoader.getResource()之间的区别是什么?

编辑:我特别想知道文件/目录级别是否涉及到缓存。比如说,“Class版本中的目录列表是否被缓存了?”

据我所知,下面的代码本质上应该是一样的,但实际上它们并不一样:

getClass().getResource()
getClass().getClassLoader().getResource()

我是在处理一些报告生成代码时发现的这个问题。该代码从WEB-INF/classes/目录中的现有文件创建一个新文件。当我使用Class的方法时,我可以通过getClass().getResource()找到部署时存在的文件,但是当我尝试获取新创建的文件时,我收到了一个空对象。浏览目录清楚地显示新文件是存在的。文件名以斜杠开头,如“/myFile.txt”。

另一方面,ClassLoader版本的getResource()确实可以找到生成的文件。根据这个经验,似乎存在某种目录列表的缓存。我是对的吗?如果是这样,这在哪里有记录?

根据Class.getResource()API文档

查找具有给定名称的资源。用于搜索与给定类关联的资源的规则由类的定义类加载器实现。此方法委托给此对象的类加载器。如果此对象是由引导类加载器加载的,则该方法委托给ClassLoader.getSystemResource(java.lang.String)。

对我来说,这意味着“Class.getResource实际上是调用它自己的类加载器的getResource()方法”。这与执行getClass().getClassLoader().getResource()相同。但显然并不是这样。请问有人能给我一些关于这个问题的启示吗?

0
0 Comments

Java资源加载(Java resource loading)是一个常见的问题,出现的原因是因为在Java中,使用不同的方法加载资源会导致不同的搜索路径。具体来说,调用getClass().getResource()方法会相对于.class文件进行搜索,而调用getClassLoader().getResource()方法会相对于类路径的根目录进行搜索。

为了调试这种问题,可以使用System.out.println()语句打印URL,例如:System.out.println( getClass().getResource(getClass().getSimpleName() + ".class") );。通过打印URL,可以更清楚地看到资源的搜索路径。

需要注意的是,如果文件名以/开头,两种方法都可以搜索绝对路径。但是有趣的是,有时候getClass().getResource("/someAbsPath")会返回一个形如/path/to/mylib.jar!/someAbsPath的URL,而getClassLoader().getResource("/someAbsPath")会返回null。这表明"类加载器的根目录"并没有一个明确定义的概念。

如果想了解更多关于这个的问题,可以参考stackoverflow.com/questions/13269556/…

Java资源加载问题的出现是因为在使用不同的方法加载资源时,搜索路径不一致。为了解决这个问题,可以根据具体的需求选择使用getClass().getResource()getClassLoader().getResource()方法。

0