Java中ClassLoader和Class的getResource()和getResourceAsStream()方法

    虽然网上关于ClassLoader和Class的getResource()和getResourceAsStream()方法的区别多的数不胜数,但是自己也遇到了这个问题,所以就记录了下来。

 

     背景:昨日由于项目中要使用ehcache缓存,所以本人新建了个Java Project。写个ehcache缓存对象的demo,于是在网上找了个例子,第一步是

      CacheManager cacheManager = CacheManager.getInstance();

      Cache cache = cacheManager.getCache(cacheName);

     

看完第一行代码感觉非常好奇。我的ehcache.xml放到src下,CacheManager.getInstance()时是怎么加载ehcache.xml的,于是打开ehcache的源码,发现在最后是有解析ehcache.xml的代码,如下图:



 


Java中ClassLoader和Class的getResource()和getResourceAsStream()方法_第1张图片
 

 

   由上图可以看到ehcache在找ehcache.xml的时候默认是先使用ClassLoader.getResource(),如果用ClassLoader的方式获取的Url为null的话,再使用Class.getResource(),但是ClassLoader的getResource()方法和Class的getResource()方法到底有什么区别呢?于是自己分别用这两种方式去测试(我新建的Java项目,默认classes文件在项目下/bin/下,ehcache.xml在src下)。

 

测试代码如下:

 

        URL resource = Thread.currentThread().getContextClassLoader().getResource("ehcache.xml");
        System.out.println(resource);

        System.out.println("-------------------------");

        InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("ehcache.xml");
        System.out.println(resourceAsStream);

        System.out.println("-------------------------");

        InputStream resourceAsStream1 = Test.class.getClassLoader().getResourceAsStream("ehcache.xml");
        System.out.println(resourceAsStream1);

        System.out.println("-------------------------");

        URL resource2 = Test.class.getResource("/ehcache.xml");
        System.out.println(resource2);

        System.out.println("-------------------------");

        InputStream resourceAsStream2 = Test.class.getResourceAsStream("/ehcache.xml");
        System.out.println(resourceAsStream2);

        System.out.println("-------------------------");

 

 

 

结果输出:

 

 

file:/E:/MyEclipse/MyEclipse4Spring2013WorkSpace/workspace/cacheTest/bin/ehcache.xml
-------------------------
java.io.BufferedInputStream@40a0dcd9
-------------------------
java.io.BufferedInputStream@1034bb5
-------------------------
file:/E:/MyEclipse/MyEclipse4Spring2013WorkSpace/workspace/cacheTest/bin/ehcache.xml
-------------------------
java.io.BufferedInputStream@7f5f5897
-------------------------

以上用ClassLoader和Class方式的getResource()和getResourceAsStream()方法都能找到ehcache.xml文件。但是仔细观察你会发现,ClassLoader的getResource()和getResourceAsStream()方法中的参数都不带"/",而Class方式的都带“/”。如果ClassLoader方式的加上"/"的话,会无法找到,Class方式的去掉"/"的话也不能找到。(可自行测试)

 

另附上不加任何文件名的方式测试:

 

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

  

结果:

file:/E:/MyEclipse/MyEclipse4Spring2013WorkSpace/workspace/cacheTest/bin/
file:/E:/MyEclipse/MyEclipse4Spring2013WorkSpace/workspace/cacheTest/bin/com/cache/test/
file:/E:/MyEclipse/MyEclipse4Spring2013WorkSpace/workspace/cacheTest/bin/
file:/E:/MyEclipse/MyEclipse4Spring2013WorkSpace/workspace/cacheTest/bin/

 

 

结论:

1、ClassLoader的getResource()和getResourceAsStream()方法找的是classpath根目录下的resource(注意不能带"/")。

2、Class的getResource()和getResourceAsStream()方法不带"/"的话找到的是当前类的同目录路径。带上"/"的话找到的是classpath根目录路径。

 

 

PS:Test.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 这样也可以获取到classpath的绝对路径。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

你可能感兴趣的:(Java中ClassLoader和Class的getResource()和getResourceAsStream()方法)