类签名:
java.lang.Class
public java.net.URL getResource(String name)
找到指定名称的资源。使用用相关类去搜索资源的规则由这个类的类加载器实现。这个方法是这个类(类对象,不是类实例)的类加载器的代理。如果当前类对象是由bootstrap 类加载器加载的,这个方法代理的是ClassLoader.getSystemResource
方法。
在代理之前,使用如下的算法,由给定的资源名,生成一个绝对的资源名(实际名称):
- 如果资源名以’/’(‘\u002f’)作为起始字符,那么实际的资源名是’/’之后的部分。
- 否则,实际的资源名为如下的格式:
modified_package_name/name
modified_package_name 是这个类的包名的替换:将 包名中间的’.’替换为’/’(‘\u002e’)。
参数:
name - 想要的资源名
Returns:
一个 java.net.URL对象,如果给定名称的资源未找到的话,返回null
Since:1.1
来看一下它的源码。
class的第一步调用了resolveName方法:
首先,在拿到给定的name参数之后,它会先对这个名字进行一下处理:
从这里我们可以看出来,如果
- name以’/’开头,即表示在当前类的classpath目录下,为什么是classpath路径下呢,下边我们会看到
- name不以’/’开头,即表示和当前类在同一个包下的文件名
由于class的getResource只是它的类加载器的方法的代理,我们直接看classloader是怎么处理的:
然后交给parent classloader处理:
最后交给ExtClassLoader处理:
URLClassPath :
在上述path必然找不到我们自定义的文件,返回null,交给AppClassLoader继续调用findResource查找:
fiindResource再次调用URLClassPath查找:
这次,我们可以在path列表中看到了我们项目所在的目录:
最终会在该路径下找到文件:
综上所述,Class的getResource(String name)方法最终会调用Class.getClassLoader().getResource(String resolveddName)方法。
同样的,我们经常在代码中看到的,通过Class.getResourceAsStream(String name)方法,其最终也是对Class.getClassLoader().getResourceAsStream(String resolveddName)的方法的调用: