文档章节

Class.getResource和ClassLoader.getResource的区别分析

李永china
 李永china
发布于 2017/08/20 11:30
字数 516
阅读 4
收藏 0

在Java中获取资源的时候,经常用到Class.getResource和ClassLoader.getResource,本文给大家说一下这两者方法在获取资源文件的路径差异。
Class.getResource(String path)
path不以'/'开头时,默认是从此类所在的包下取资源;path以'/'开头时,则是从项目的ClassPath根下获取资源。在这里'/'表示ClassPath
JDK设置这样的规则,是很好理解的,path不以'/'开头时,我们就能获取与当前类所在的路径相同的资源文件,而以'/'开头时可以获取ClassPath根下任意路径的资源。
如下所示的例子:

1

2

3

4

5

6

7

8

public class Test

{

    public static void main(String[] args)

    {

        System.out.println(Test.class.getResource(""));

        System.out.println(Test.class.getResource("/"));

    }

}

运行结果为:
file:/D:/work_space/java/bin/net/swiftlet/
file:/D:/work_space/java/bin/

Class.getClassLoader().getResource(String path)
path不能以'/'开头时,path是指类加载器的加载范围,在资源加载的过程中,使用的逐级向上委托的形式加载的,'/'表示Boot ClassLoader中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null。如下所示:

1

2

3

4

5

6

7

8

public class Test

{

    public static void main(String[] args)

    {

        System.out.println(Test.class.getClassLoader().getResource(""));

        System.out.println(Test.class.getClassLoader().getResource("/"));

    }

}

运行结果为:
file:/D:/work_space/java/bin/
null
从上面可以看出:
class.getResource("/") == class.getClassLoader().getResource("")
其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。下面请看一下jdk的Class源码:

1

2

3

4

5

6

7

8

9

10

11

  public java.net.URL getResource(String name)

    {

        name = resolveName(name);

        ClassLoader cl = getClassLoader0();

        if (cl==null)

        {

            // A system class.

            return ClassLoader.getSystemResource(name);

        }

        return cl.getResource(name);

    }

从上面就可以看才出来:Class.getResource和ClassLoader.getResource本质上是一样的。至于为什么Class.getResource(String path)中path可以'/'开头,是因为在name = resolveName(name);进行了处理:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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;

    }

本文转载自:http://swiftlet.net/archives/868

李永china
粉丝 11
博文 233
码字总数 174289
作品 0
朝阳
程序员
私信 提问
java 路径寻址Class.getResource和ClassLoader.getResource

以下内容参考、学习自下面两篇博客 关于Class.getResource和ClassLoader.getResource的路径问题 Class.getResource和ClassLoader.getResource的区别分析 Class.getResource(String path) pat...

不开心时不要学习
2018/07/08
252
0
Class和ClassLoader.getResource获取资源

资源就是系统内、项目内的各种文件。在Java中获取可以用File类和Class.getResource获取资源,直观的说,File是依赖于文件系统和操作系统的,通过相对和绝对路径定位,使用File接口可以用于获...

lonewolfxuwei
2014/05/15
0
0
Java 获取资源路径的3种方法与区别

◆一般情况下,我们都使用相对路径来获取资源,这样的灵活性比较大. 比如当前类为com/ketqi/Test.class 而图像资源比如sample.gif应该放置在com/ketqi/sample.gif 而如果这些图像资源放置在ico...

lzw_me
2014/05/04
43
0
Java_Path_01_路径问题

二、参考资料 1.java 路径问题 2.Java路径问题最终解决方案—可定位所有资源的相对路径寻址 3.Java获取文件的路径 4.Thread.currentThread().getContextClassLoader()与Test.class.getClass...

rayner
2018/01/08
0
0
java相对目录和绝对目录解析

转自:http://blog.csdn.net/ruyanhai/archive/2007/11/07/1871663.aspx ◆一般情况下,我们都使用相对路径来获取资源,这样的灵活性比较大. 比如当前类为com/bbebfe/Test.class 而图像资源比如...

sinpo
2012/02/29
73
0

没有更多内容

加载失败,请刷新页面

加载更多

Android面试常客之Handler全解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/fnhfire_7030/article/details/79518819 前言:又到了一年...

shzwork
7分钟前
0
0
position sticky 定位

本文转载于:专业的前端网站➫position sticky 定位 1、兼容性 https://caniuse.com/#search=sticky chrome、ios和firefox兼容性良好。 2、使用场景 sticky:粘性。粘性布局。 在屏幕范围内时...

前端老手
14分钟前
1
0
CentOS 7 yum 安装 PHP7.3 教程

参考:https://www.mf8.biz/centos-rhel-install-php7-3/ 1、首先安装 EPEL 源: yum install epel-release 安装 REMI 源: yum install http://rpms.remirepo.net/enterprise/remi-release......

dragon_tech
28分钟前
1
0
Linux物理网卡聚合及桥接

Linux内部实现的bridge可以把一台机器上的多张网卡桥接起来,从而把自己作为一台交换机。同时,LInux bridge还支持虚拟端口,即桥接的不一定都是物理网卡接口,还可以是虚拟接口。目前主要表...

xiangyunyan
29分钟前
1
0
一起来学Java8(一)——函数式编程

在这篇文章中,我们将了解到在Java8下如何进行函数式编程。 函数式编程 所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。 首先来看下JavaScript如何进行函...

猿敲月下码
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部