zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    分割回文串(力扣第131题)
    子集 II(力扣第91题)
    子集(力扣第78题)
    组合总和 III(力扣第216题)
    JavaWeb部分 (前序)
    JavaSE部分 (IO流下)
    JavaSE部分 (IO流上)
    JavaSE部分 (File类)
    Leetcode 08.04 幂集 回溯与位图
    Leetcode 1405 最长快乐字符串 穷举与贪心
  • 原文地址:https://www.cnblogs.com/softidea/p/4251433.html
Copyright © 2011-2022 走看看