resource获取方法之一,java.lang.Class的getResource

resource获取方法之一,java.lang.Class的getResource

可参考这两个:

http://stackoverflow.com/questions/3861989/preferred-way-of-loading-resources-in-java

http://www.thinkplexx.com/learn/howto/java/system/java-resource-loading-explained-absolute-and-relative-names-difference-between-classloader-and-class-resource-loading

主要说说this.getClass().getResource(String name),即JDK中java.lang.Class的方法public java.net.URL getResource(String name),返回一个URL对象。

有两种情况,看看这个例子:http://www.cnblogs.com/yejg1212/p/3270152.html

参数以’/’开头

从ClassPath根下获取,eclipse maven工程就是target/classes/或target/test-classes/

参数非’/’开头

从此类所在的package下取资源

如何实现的呢?

官方API:http://docs.oracle.com/javase/8/docs/api/index.html

Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the defining class loader of the class. This method delegates to this object’s class loader. If this object was loaded by the bootstrap class loader, the method delegates to ClassLoader.getSystemResource(java.lang.String).

Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:

If the name begins with a ‘/’ (‘\u002f’), then the absolute name of the resource is the portion of the name following the ‘/’.

Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with ‘/’ substituted for ‘.’ (‘\u002e’).

大致意思是:这个方法会将动作委托至这个对象的classLoader进行(还会涉及到这个classLoader 的parent classLoader),若不存在委托SystemClassLoader或者bootstrap class loader(应该涉及到双亲委派的内容)。主要说说参数,若以’/’开头则是相对于ClassPath的路径,不以’/’开头则是相对于该类文件所在位置路径,其原理是获取类全名,解析为该类所在位置相对于ClassPath的路劲,再拼接上入参。

看看源码

public java.net.URL getResource(String name) {
    name = resolveName(name);//这一步会对参数进行解析,区分是否以'/'情况
    ClassLoader cl = getClassLoader0();//获取这个对象的ClassLoader
    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();
        }
        //获取该类的全名,去除类名,把点替换为路劲分隔符,再加上入参
        //如 A.B.C.className --> A.B.C --> A/B/C --> A/B/C/name
        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;
}

最后,调用该方法之后记得判空~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值