Java类路径之getResource 和 getResourceAsStream

来源:互联网 发布:文明5 mac 配置 编辑:程序博客网 时间:2024/06/03 11:21

类签名:

java.lang.Classpublic java.net.URL getResource(String name)

找到指定名称的资源。使用用相关类去搜索资源的规则由这个类的类加载器实现。这个方法是这个类(类对象,不是类实例)的类加载器的代理。如果当前类对象是由bootstrap 类加载器加载的,这个方法代理的是ClassLoader.getSystemResource方法。

在代理之前,使用如下的算法,由给定的资源名,生成一个绝对的资源名(实际名称):

  1. 如果资源名以’/’(‘\u002f’)作为起始字符,那么实际的资源名是’/’之后的部分。
  2. 否则,实际的资源名为如下的格式:
modified_package_name/name

modified_package_name 是这个类的包名的替换:将 包名中间的’.’替换为’/’(‘\u002e’)。

参数:
name - 想要的资源名
Returns:
一个 java.net.URL对象,如果给定名称的资源未找到的话,返回null
Since:1.1

来看一下它的源码。

caller

class的第一步调用了resolveName方法:

getresource

首先,在拿到给定的name参数之后,它会先对这个名字进行一下处理:

resolvename

从这里我们可以看出来,如果

  1. name以’/’开头,即表示在当前类的classpath目录下,为什么是classpath路径下呢,下边我们会看到
    zz.properties
  2. name不以’/’开头,即表示和当前类在同一个包下的文件名
    xx.txt

由于class的getResource只是它的类加载器的方法的代理,我们直接看classloader是怎么处理的:

classloader_getresource

然后交给parent classloader处理:

parent_classloader

最后交给ExtClassLoader处理:

ExeclassLoader

bootstrapResource

URLClassPath :

URLClassPath

在上述path必然找不到我们自定义的文件,返回null,交给AppClassLoader继续调用findResource查找:

AppClassLoader

fiindResource再次调用URLClassPath查找:

findResource

这次,我们可以在path列表中看到了我们项目所在的目录:

ucp

最终会在该路径下找到文件:

fined

综上所述,Class的getResource(String name)方法最终会调用Class.getClassLoader().getResource(String resolveddName)方法。

同样的,我们经常在代码中看到的,通过Class.getResourceAsStream(String name)方法,其最终也是对Class.getClassLoader().getResourceAsStream(String resolveddName)的方法的调用:

getStream

0 0