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


 

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM