getResource/getResourceAstream

getResource/getResourceAstream

示例


package com.lh.st.classloader;

public class ClassLoaderLearn {
    public static void main(String[] args) {
        //file:/Users/lh/java_st/java-base/target/classes/
        System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
        //null
        System.out.println(Thread.currentThread().getContextClassLoader().getResource("/"));
        //file:/Users/lh/java_st/java-base/target/classes/
        System.out.println(ClassLoaderLearn.class.getClassLoader().getResource(""));
        //null
        System.out.println(ClassLoaderLearn.class.getClassLoader().getResource("/"));
        //file:/Users/lh/dp_arch/Log4jLearning/target/classes/com/lh/classloader/
        System.out.println(ClassLoaderLearn.class.getResource(""));
        //file:/Users/lh/dp_arch/Log4jLearning/target/classes/
        System.out.println(ClassLoaderLearn.class.getResource("/"));
        //com.lh.st.classloader.ClassLoaderLearn
        System.out.println(ClassLoaderLearn.class.getName());
        System.out.println(ClassLoaderLearn.class.getResource("/com/lh/st/classloader/"));
        //file:/Users/lh/java_st/java-base/target/classes/com/lh/st/classloader/ClassLoaderLearn.class
        System.out.println(ClassLoaderLearn.class.getResource("ClassLoaderLearn.class"));
    }
}

Class的getResource和getResourceAsstream方法最终还是调用ClassLoader的getResource和getResourceAsstream方法。

总结

  1. Class.getResourceAsStream(String path) : path 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从
    ClassPath根下获取。

  2. Class.getClassLoader.getResourceAsStream(String path) :默认则是从ClassPath根下获取,path不能以’/'开头,最终是由
    ClassLoader获取资源。

Class 的getResource 和 getReourceAsStream

getResource()

    public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResource(name);
        }
        //还是调用的ClassLoader的getResource
        return cl.getResource(name);
    }

Class的getResource()最终还是调用的ClassLoader的getReource().首先找到类加载器,如果类加载器是null,说明是根加载器,调用ClassLoader.getSystemResource(name)

resolveName()

    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;
    }

如果以/开头,返回/后面的字符串。如果不是以/开头,返回 (当前包路径+name)

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);
    }

和getResource一样,最终也是调用ClassLoader的getResourceAsstream方法

ClassLoader的 getResource 和 getResourceAsstream

getResource()

    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;
    }

首先父加载器中查找,然后根加载器中查找,如果没有,则返回null

getResourceAstream()

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

调用getResource方法得到URL,然后获取打开资源的流

你可能感兴趣的:(getResource/getResourceAstream)