getResource(String name)用法及源码分析

简介: Project获取资源需要一个启点,加载资源的动作是由ClassLoader来完成的。Class对象和当前线程对象可以找到当前加载资源的ClassLoader,通过ClassLoader的getResource(String name)方法及其它衍生出来的方法可以找到Application...

 

Project获取资源需要一个启点,加载资源的动作是由ClassLoader来完成的。
Class对象和当前线程对象可以找到当前加载资源的ClassLoader,
通过ClassLoader的getResource(String name)方法及其它衍生出来的方法可以找到Application的启点及获取相关资源
    
private void display() { path=this.getClass().getResource("/loadresource").getPath(); System.out.println(path); path=this.getClass().getResource("/loadresource/bp.txt").getPath(); System.out.println(path); path=this.getClass().getResource("/").getPath(); System.out.println(path); URL url=this.getClass().getResource("loadresource/bp.txt"); System.out.println("Is Null:"+(url==null)); path=GetResouceTest.class.getClassLoader().getResource("").getPath(); System.out.println(path); path=GetResouceTest.class.getClassLoader().getResource("loadresource/bp.txt").getPath(); System.out.println(path); url=GetResouceTest.class.getClassLoader().getResource("/loadresource/bp.txt"); System.out.println("Is Null:"+(url==null)); path=Thread.currentThread().getContextClassLoader().getResource("").getPath(); System.out.println(path); path=Thread.currentThread().getContextClassLoader().getResource("loadresource/bp.txt").getPath(); System.out.println(path); url=Thread.currentThread().getContextClassLoader().getResource("loadresource/bp.txt"); System.out.println("Is Null:"+(url==null)); url=Thread.currentThread().getContextClassLoader().getResource("/loadresource/bp.txt"); System.out.println("Is Null:"+(url==null)); }

 

Output:

/E:/java/workspace/test/bin/loadresource
/E:/java/workspace/test/bin/loadresource/bp.txt
/E:/java/workspace/test/bin/
Is Null:true
/E:/java/workspace/test/bin/
/E:/java/workspace/test/bin/loadresource/bp.txt
Is Null:true
/E:/java/workspace/test/bin/
/E:/java/workspace/test/bin/loadresource/bp.txt
Is Null:false
Is Null:true

 

Conclusion:
java.lang.Class<T>的URL  getResource(String name)时可以使用参数:
(1)"/":代表项目根目录,也就是ClassPath的root

(2)以"/"开头的包路径

java.lang.ClassLoader的URL getResource(String name)时使用参数:
(1)"":代表项目根目录,也就是ClassPath的root
(2)不以"/"开头的包路径

源码解析:

java.lang.Class

 /**
     * Finds a resource with a given name.  The rules for searching resources
     * associated with a given class are implemented by the defining
     * {@linkplain ClassLoader 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 {@link
     * ClassLoader#getSystemResource}.
     *
     * <p> Before delegation, an absolute resource name is constructed from the
     * given resource name using this algorithm:
     *
     * <ul>
     *
     * <li> If the {@code name} begins with a {@code '/'}
     * (<tt>'&#92;u002f'</tt>), then the absolute name of the resource is the
     * portion of the {@code name} following the {@code '/'}.
     *
     * <li> Otherwise, the absolute name is of the following form:
     *
     * <blockquote>
     *   {@code modified_package_name/name}
     * </blockquote>
     *
     * <p> Where the {@code modified_package_name} is the package name of this
     * object with {@code '/'} substituted for {@code '.'}
     * (<tt>'&#92;u002e'</tt>).
     *
     * </ul>
     *
     * @param  name name of the desired resource
     * @return      A  {@link java.net.URL} object or {@code null} if no
     *              resource with this name is found
     * @since  JDK1.1
     */
    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);
    }
   /**
     * Add a package name prefix if the name is not absolute Remove leading "/"
     * if name is absolute
     */
    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;
    }

从源码看:
(1)java.lang.Class的getResource(String name)方法调用了ClassLoader的getResource(String name)方法;

(2)java.lang.Class的resolveName(String name)方法去掉了name中的第一个字符“/”,

java.lang.Classloader的getResource(String name)的参数name首字母没有“/”

Extension section

如果路径中有空格及中文在某些场景会出来问题。

可以尝试在getResource(Sting name).toURL()来解决。

http://www.cnblogs.com/softidea/p/3888829.html

 

目录
打赏
0
0
0
0
95
分享
相关文章
|
10月前
|
C++string类的介绍及常用函数用法总结
C++string类的介绍及常用函数用法总结
107 1
抽象类和接口 && String的理解 && StringBuilder和StringBuffer && 异常的基本用法 && 时间复杂度
抽象类和接口 && String的理解 && StringBuilder和StringBuffer && 异常的基本用法 && 时间复杂度
79 0
|
7月前
|
文本匹配.grep与Select-String用法对比
文本匹配.grep与Select-String用法对比
100 6
|
8月前
|
C++
C++ string中的函数和常用用法
C++ 中string中的函数和常用用法
73 4
【BUG记录】Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x90\xA6' for column 'name' at row 1
在MySQL中遇到`Incorrect string value`错误通常是因为尝试插入的字符串包含不被数据库字符集支持的字符,如表情符号。错误根源是MySQL默认的utf8不支持4字节的UTF-8字符(如Emoji)。
1024 1
|
9月前
|
Java中String的用法
Java中String的用法
79 1
|
9月前
|
StringBuffer,StringBuilder的区别及其源码分析
StringBuffer,StringBuilder的区别及其源码分析
【Java用法】Java中String类型和int类型互转的所有方法
【Java用法】Java中String类型和int类型互转的所有方法
197 0
|
9月前
|
#include <string>的用法
#include <string>的用法
172 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等