zoukankan      html  css  js  c++  java
  • Class的getResource与ClassLoader的getResource路径/问题

    一、Class的getResource(String path):URL

    1、path 不以’/'开头时,默认是从此类所在的包下取资源;
    2、path 以’/'开头时,则是从ClassPath根下获取;
    System.out.println(Test.class.getResource(""));
    System.out.println(Test.class.getResource("/"));
    file:/E:/java/Test/bin/cn/
    file:/E:/java/Test/bin/

    二、类加载器ClassLoader的getResource(String path)

    1、path 不以'/'开头

         path是指类加载器的加载范围,在资源加载的过程中,使用的逐级向上委托的形式加载的,加载范围是从整个ClassPath范围。

    2、path 以'/'开头

         '/'表示Boot ClassLoader中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null

    System.out.println(Test.class.getClassLoader().getResource(""));
    System.out.println(Test.class.getClassLoader().getResource("/"));

      file:/E:/java/Test/bin/
      null

    三、class.getResource("/") 等价于 class.getClassLoader().getResource("")

    class.getResource()与classLoader().getResource()最终使用了系统类加载器加载以classpath为根不带'/'的路径进行加载资源

    Class的getResource方法源码

    public URL getResource(String name){
            name = resolveName(name);//将路径转换成为classpath根的绝对路径,不以/开头
            ClassLoader cl = getClassLoader0();
            if (cl==null)
            {
                // A system class.
                return ClassLoader.getSystemResource(name);
            }
            return cl.getResource(name);
    }

     getClassLoader0方法与resolveName方法

    //获取当前类的类加载器
    ClassLoader getClassLoader0(){
        return classLoader; 
    }
    
    //获取classpath根的绝对路径,不以/开头
    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;
    }
    View Code

    ClassLoader.getSystemResource方法

    public static URL getSystemResource(String name) {
         //返回委派的系统类加载器。这是默认代表团的父母新的类加载器实例,并通常用于启动应用程序的类加载器。
        ClassLoader system = getSystemClassLoader();
        if (system == null) {
                return getBootstrapResource(name);//根据根加载器的路径检索资源
        }
        return system.getResource(name);
    }
    // The class loader for the system
    private static ClassLoader scl;
    public static ClassLoader getSystemClassLoader() {
        initSystemClassLoader();
        if (scl == null) {
           return null;
        }
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
           checkClassLoaderPermission(scl, Reflection.getCallerClass());
        }
        return scl;
    }
    View Code

    ClassLoader.getResource方法源码

    private final ClassLoader parent;
    public URL getResource(String name) {
            URL url;
            //父加载器非null
            if (parent != null) {
                url = parent.getResource(name);  //请求父加载器获取资源
            } else {
                url = getBootstrapResource(name); //该类为ExtClassLoader,用其父加载器Bootstrap加载资源
            }
            if (url == null) {
                url = findResource(name);
            }
            return url;
    }
    //从虚拟机的内置类加载器查找资源
    private static URL getBootstrapResource(String name) {
         URLClassPath ucp = getBootstrapClassPath();
         Resource res = ucp.getResource(name); 
         return res != null ? res.getURL() : null;
    }
    
    //返回urlclasspath是用于发现系统资源。
    static URLClassPath getBootstrapClassPath() {
          return sun.misc.Launcher.getBootstrapClassPath();
    }
  • 相关阅读:
    HDOJ 2076 夹角有多大(题目已修改,注意读题)
    HDOJ 2058 The sum problem
    HDOJ 2099 整除的尾数
    HDOJ 2075 A|B?
    HDOJ 2071 Max Num
    HDOJ 2056 Rectangles
    HDOJ 2055 An easy problem
    HDOJ 2053 Switch Game
    HDOJ 2052 Picture
    P4139 上帝与集合的正确用法
  • 原文地址:https://www.cnblogs.com/maokun/p/6770426.html
Copyright © 2011-2022 走看看