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


    Class.getResource(String path)
    path不以'/'开头时,默认是从此类所在的包下取资源;path以'/'开头时,则是从项目的ClassPath根下获取资源。在这里'/'表示ClassPath
    JDK设置这样的规则,是很好理解的,path不以'/'开头时,我们就能获取与当前类所在的路径相同的资源文件,而以'/'开头时可以获取ClassPath根下任意路径的资源。

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

    package xyz.**.demo;
    public class DemoTest {
    @Test
    public void testDemo() {
    System.out.println(getClass().getResource(""));
    System.out.println(getClass().getResource("/"));
    System.out.println(getClass().getClassLoader().getResource(""));
    System.out.println(getClass().getClassLoader().getResource("/"));
    }
    }

     打印结果result:

    file:/D:/worker/demo/target/test-classes/xyz/**/demo/
    file:/D:/worker/demo/target/test-classes/
    file:/D:/worker/demo/target/test-classes/
    null

    从上面可以看出:
    class.getResource("/") == class.getClassLoader().getResource("")
    其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。下面请看一下jdk的Class源码:

    getClassLoader().getResource:

     public URL getResource(String name) {
    URL url;
    if (parent != null) {
    url = parent.getResource(name);
    } else {
    url = getBootstrapResource(name);
    }
    if (url == null) {
    url = findResource(name);
    }
    return url;
    }

     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);
    }

    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;
    }

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

    classpath:只会到你的class路径中查找找文件;
    classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找

  • 相关阅读:
    IsPostBack
    多次点击Button后DropDownList选中的值变为默认值?
    数据表数据的复制
    使用DriverManager获取数据库连接
    通过Driver获取数据库连接
    URL学习笔记
    使用UDP进行数据发送的实例一
    利用Socket 客户端---->服务端 传送文件到指定路径,并返回一个友好的回馈
    关于TCP的两个小练习_第一个博客~
    oracle-19c-单实例安装-一键式脚本
  • 原文地址:https://www.cnblogs.com/leifonlyone/p/12674576.html
Copyright © 2020-2023  润新知