栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java(47):学习Class.getResource和ClassLoader.getResource

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java(47):学习Class.getResource和ClassLoader.getResource

====》getResource方法是得到文件路径的函数。

获取文件的路径,使用时主要是两种方法, 一个是字节码文件Class类, 另一个是ClassLoader类加载器

使用Class类时有两种使用方式:

1、不使用"/" 这就是具体该类的路径

2、使用"/"  获取到的是classpath路径

ClassLoader类

1、没有"/"的写法, 直接写文件名获取到的就是classpath路径

其实如果读取class下面的这里就用:

PropertiesUtil.class.getClassLoader().getResource("").getPath()获取就可以。

System.out.println(PropertiesUtil.class.getResource("").getPath());  -->PropertiesUtil.class类所在的位置

System.out.println(PropertiesUtil.class.getResource("/").getPath());  -->classpath的路径

System.out.println(PropertiesUtil.class.getClassLoader().getResource("").getPath());-->classpath的路径

System.out.println(PropertiesUtil.class.getClassLoader().getResource("/"));  -->classpath的路径

一、Class.getResource源码解析

看下具体例子:

 看下System.out.println(PropertiesUtil.class.getResource("").getPath());的调用。

方法getResource("")的源码:

public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();   // 获取加载该Class的ClassLoader
        if (cl==null) {//如果加载该Class的ClassLoader为null,则表示这是一个系统class
            // A system class.
            return ClassLoader.getSystemResource(name);  
        }
        return cl.getResource(name); /调用ClassLoader的getResource方法
    }

下面是ClassLoader的getResource方法

public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();   // 获取加载该Class的ClassLoader
        if (cl==null) {//如果加载该Class的ClassLoader为null,则表示这是一个系统class
            // A system class.
            return ClassLoader.getSystemResource(name);  
        }
        return cl.getResource(name); /调用ClassLoader的getResource方法
    }

下面是ClassLoader的getResource方法

public URL getResource(String name) {
        URL url;
        if (parent != null) {  //这里的parent为sun.misc.Launcher$ExtClassLoader@7d4793a8
            url = parent.getResource(name);//这里是一个递归调用,再次进入之后parent为null
        } else {
            url = getBootstrapResource(name);//到达系统启动类加载器
        }
        if (url == null) {//系统启动类加载器没有加载到,递归回退到第一次调用然后是扩展类加载器
            url = findResource(name);
        }
        return url;//最后如果都没有加载到,双亲委派加载失败,则加载应用本身自己的加载器
    }

getResource()方法中name = resolveName(name);

 private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) { -->//对于不以/开头的文件,
            Class c = this;  //获取当前加载类的完整的类路径,例如:/com/ciphergateway/utils/
            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;
    }

具体说明:

Class.getResource和ClassLoader.getResource 最终调用的是ClassLoader 类的getResource方法。只不过Class.getResource是先调用Class 的 getResource 方法,在这个getResource  方法中,再去调用ClassLoader 类的getResource方法。

二、对于:class.getResource("")

1、PropertiesUtil.class.getResource("").getPath()

Class类中的getResource方法返回的是/com/ciphergateway/utils/ (获取当前加载类的完整的类路径)

ClassLoader类中的getResource方法返回的是

 /D:/java_project2021/autocasb/target/classes/com/ciphergateway/utils/

这里获取的文件路径其实是:/D:/java_project2021/autocasb/target/classes/com/ciphergateway/utils/

  1. PropertiesUtil.class.getResource("/").getPath()

Class类中的getResource方法返回的是""

ClassLoader类中的getResource方法返回的是 file:/C:/myroad/utalitityUtils/target/classes/

  1. PropertiesUtil.class.getClassLoader().getResource("").getPath()

class.getClassLoader().getResource("")返回的是target/class/

这里获取的文件路径其实是:/D:/java_project2021/autocasb/target/classes

三、对于ClassLoader.getResource

PropertiesUtil.class.getClassLoader().getResource("").getPath()

直接调用的就是ClassLoader 类的getResource方法,那么对于getResource(""),通过当前类加载classpath根下资源文件。

所以这里的路径是:/D:/java_project2021/autocasb/target/classes

四、Class.getResource和ClassLoader.getResource的区别

就是在加载资源文件的时候,加载方式的不同,

class.getResource("/") == class.getClassLoader().getResource("")

其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。

Class.getResource真正调用ClassLoader.getResource方法之前,会先获取文件的路径(path不以'/'开头时,默认是从此类所在的包下取资源;path以'/'开头时,则是从项目的ClassPath根下获取资源)。

ClassLoader.getResource方法会通过双亲委派机制,先委派双亲去加载类,如果双亲没有加载到,则再由自己加载。

classLoader加载顺序,详见https://blog.csdn.net/eff666/article/details/52203406

参考:

https://blog.csdn.net/zhangshk_/article/details/82704010

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/343165.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号