Java getResource

最近在工作中有用到资源加载、发现 ClassClassLoader 都可以加载 classPath 下的文件

对比一下他们之间的异同

微信公众号:CoderLi
package com.demo.test.get;

public class GetResourceMain {
    public static void main(String[] args) {
      
        Class<GetResourceMain> getResourceMainClass = GetResourceMain.class;
        ClassLoader classLoader = getResourceMainClass.getClassLoader();

        System.out.println("classGetResource:" + getResourceMainClass.getResource(""));
        System.out.println("classLoaderGetResource:" + classLoader.getResource(""));

        System.out.println("/ classGetResource:" + getResourceMainClass.getResource("/"));
        System.out.println("/ classLoaderGetResource:" + classLoader.getResource("/"));

        System.out.println("logback.xml classGetResource:" + getResourceMainClass.getResource("logback.xml"));
        System.out.println("logback.xml classLoaderGetResource:" + classLoader.getResource("logback.xml"));

        System.out.println("/logback.xml classGetResource:" + getResourceMainClass.getResource("/logback.xml"));
        System.out.println("/logback.xml classLoaderGetResource:" + classLoader.getResource("/logback.xml"));

        System.out.println("jar inner file classLoaderGetResource:" + classLoader.getResource("META-INF/maven/org.slf4j/slf4j-api/pom.xml"));

    }
}

classGetResource:file:/Users/xxxx/IdeaProjects/logbackTest/target/classes/com/demo/test/get/
classLoaderGetResource:file:/Users/xxxx/IdeaProjects/logbackTest/target/classes/
/ classGetResource:file:/Users/xxxx/IdeaProjects/logbackTest/target/classes/
/ classLoaderGetResource:null
logback.xml classGetResource:null
logback.xml classLoaderGetResource:file:/Users/xxxx/IdeaProjects/logbackTest/target/classes/logback.xml
/logback.xml classGetResource:file:/Users/xxxx/IdeaProjects/logbackTest/target/classes/logback.xml
/logback.xml classLoaderGetResource:null
jar inner file classGetResource:jar:file:/Users/xxxx/.m2/repository/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar!/META-INF/maven/org.slf4j/slf4j-api/pom.xml
jar inner file classLoaderGetResource:jar:file:/Users/xxxx/.m2/repository/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar!/META-INF/maven/org.slf4j/slf4j-api/pom.xml

通过日志分析我们得知 Class#getResouce 如果传入的参数以 / 开头的话则获取到的是当前 classpath 的绝对路径。如果不是的话、则是获取到当前 class 所在的路径

ClassLoader#getResource 则默认获取到的就是 classpath 下的路径、如果传入的参数以 / 开头则返回 null

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

双亲委派机制、先给父类加载器中尝试加载、然后再到自己的。

Class#getResource

最终还是调用 ClassLoader

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

这个关键在于对 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 的全路径、然后替换 . 然后返回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值