虽然网上关于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的代码,如下图:
由上图可以看到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的绝对路径。
相关推荐
这样,每次调用代理类中的方法,都会先检查实现类的class文件是否是最新的,如果不是则重新加载,达到动态加载实现类class的目的。 关键字: Java实现热加载; Java动态加载class; Java覆盖已加载的class; Java...
详细介绍java中的类加载器的使用,以及在在使用过程中需要注意的知识点
破解java加密的ClassLoader.java,在classloader植入破解代码
java classloader classpath 张孝祥
深入了解Java_ClassLoader,Bytecde.pdf
Java_ClassLoader详解,解说java类的加载的原理,让你轻松了解java的类加载
Java ClassLoader定制实例
1.java classloader 的概述 2.java classloader 的分类 3.自定义 java classloader
Java中ClassLoader的解析,从ClassLoader的角度分析了JVM,装载类,创建类的对象的整个过程,更清晰的了解JVM的运行机制。
Java 虚拟机中ClassLoader 相关简介 双亲委托机制 Android 中ClassLoader 简介
测试普通Java程序ClassLoader等级关系的Demo程序
理解Java ClassLoader机制
很容易被反编译工具反编译,而传统的java源代码保护方法基本都是采用混淆的方式, 但这样会带来很多麻烦,而且也不能真正保护class文件, 本工具是对class文件进行加密,采用jni的方式解密运行, 加密算法达到256位...
破解java加密的rt.jar,在classloader植入破解代码,默认输出到c:/TEMP/classes/目录。使用方法:只要下载本rt.jar,然后替换掉jdk1.8.0_25\jre\lib目录下的rt.jar。然后运行你需要破解的java程序即可,如果你的java...
Sun 官方关于 ClassLoader原理的文章,值得一看
Java ClassLoader Tutorial
深入Java虚拟机_ClassLoader深入Java虚拟机_ClassLoader
NULL 博文链接:https://sbiigu.iteye.com/blog/260456
内容简介: ClassLoader体系结构 类装载器在JVM中并不是唯一的,JVM自带了三个装载器,用户也可以根据自己的需求自定义新的装载器,这些装载器的体系结构可以看作是树状结构,如图1所示: