class、classLoader的getResourceAsStream的区别

1、class.getResourceAsStream()

  从源码中可以看出他也是调用ClassLoader的getResourceAsStream()

public InputStream getResourceAsStream(String name) {
     //对资源名进行解析
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }

 private String resolveName(String name) {
        if (name == null) {
            return name;
        }
       
        if (!name.startsWith("/")) {
            Class<?> c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            //获取class的全限定名,然后与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;
    }

至此Class.getResourceAsStream()也就明白了。

2、ClassLoader.getResourceAsStream()

  也从源码可以看出,他是才用委托的方式进行资源的加在,如果委托的方式没加载到相应的资源。那就通过他自己进行处理了

   public InputStream getResourceAsStream(String name) {

        URL url = getResource(name);
        try {
            return url != null ? url.openStream() : null;
        } catch (IOException e) {
            return null;
        }
    }

 public URL getResource(String name) {
        URL url;
    //通过父加载器进行资源加在 if (parent != null) {
url = parent.getResource(name); } else { url = getBootstrapResource(name); }
//父加载器加在资源失败,则通过自身进行查找 if (url == null) { url = findResource(name); } return url; }

  

总结:

  Class.getResourceAsStream()  可以指定相对路径,也可以指定绝对路径

  ClassLoader.getResourceAsStream()先通过父加载器进行加载,如果没加载到就看具体的findResource()的实现了。当然对于一般程序而言,都是从类路径下进行查找。因为我们自己的class都是通过AppClassLoader进行加载的

原文地址:https://www.cnblogs.com/zhengqun/p/5387203.html