ClassLoader.getResourceAsStream() 与 Class.getResourceAsStream()的区别
2015-12-20 17:43
197 查看
Class.getResourceAsStream() 会指定要加载的资源路径与当前类所在包的路径一致。
例如你写了一个MyTest类在包com.test.mycode 下,那么
如果这个name是以 ‘/’ 开头的,那么就会从classpath的根路径下开始查找。
ClassLoader.getResourceAsStream() 无论要查找的资源前面是否带’/’ 都会从classpath的根路径下查找。
所以:
顺便提下JAVA中类的加载器:
一共有三种加载器
bootstrap classloader :负责加载JAVA核心类( jre 下lib和class目录中的内容)
extension classloader :负责加载JAVA扩展类(jre 下lib/ext 目录中的内容)
system classloader :负责加载应用指定的类 (环境变量classpath中配置的内容)
一个类的加载顺序也是按上面的排列来的,这样就能保证系统的类能先加载。
与此同时用户也可以自己定义ClassLoader,用来加载特殊的资源。
这里就涉及到 Class.getClassLoader() 和 Thread.currentThread.getContextClassLoader()的区别。
举一个简单的例子:
假如某天JAVA给我们提供了一个叫 StartCamera 的类用来启动电脑的标准摄像头,并将这个类打包在一个jar中。
正常情况下,我们要启动摄像头时只需将这个jar配置到classpath中。系统启动时system classloader会将这个类加载到应用中。
但因为摄像头的生产厂家不一样,针对新的设备会有多个不同的StartCamera实现,在应用中我们不知道实际的用户会用到哪种。于是我们就自定义了一个ClassLoader,用来针对具体的设备类型加载相应的StartCamera类。
这样一来就出现:优先加载我们定义的类,加载不到的情况下再加载系统的。 这样的需求,是系统默认的父委托加载机制无法满足的。
那么上面的加载代码就可能是这样子的:
例如你写了一个MyTest类在包com.test.mycode 下,那么
MyTest.class.getResourceAsStream("name")会在com.test.mycode包下查找相应的资源。
如果这个name是以 ‘/’ 开头的,那么就会从classpath的根路径下开始查找。
ClassLoader.getResourceAsStream() 无论要查找的资源前面是否带’/’ 都会从classpath的根路径下查找。
所以:
MyTest.class.getResourceAsStream("/name")和
MyTest.getClassLoader().getResourceAsStream("name")的效果是一样的。
顺便提下JAVA中类的加载器:
一共有三种加载器
bootstrap classloader :负责加载JAVA核心类( jre 下lib和class目录中的内容)
extension classloader :负责加载JAVA扩展类(jre 下lib/ext 目录中的内容)
system classloader :负责加载应用指定的类 (环境变量classpath中配置的内容)
一个类的加载顺序也是按上面的排列来的,这样就能保证系统的类能先加载。
与此同时用户也可以自己定义ClassLoader,用来加载特殊的资源。
这里就涉及到 Class.getClassLoader() 和 Thread.currentThread.getContextClassLoader()的区别。
举一个简单的例子:
假如某天JAVA给我们提供了一个叫 StartCamera 的类用来启动电脑的标准摄像头,并将这个类打包在一个jar中。
正常情况下,我们要启动摄像头时只需将这个jar配置到classpath中。系统启动时system classloader会将这个类加载到应用中。
但因为摄像头的生产厂家不一样,针对新的设备会有多个不同的StartCamera实现,在应用中我们不知道实际的用户会用到哪种。于是我们就自定义了一个ClassLoader,用来针对具体的设备类型加载相应的StartCamera类。
这样一来就出现:优先加载我们定义的类,加载不到的情况下再加载系统的。 这样的需求,是系统默认的父委托加载机制无法满足的。
Thread.currentThread.getContextClassLoader()就是这样产生的。 我们使用
Thread.currentThread.setContextClassLoader()可以为当前线程指定相应的ClassLoader,然后用get的方式来获取。
那么上面的加载代码就可能是这样子的:
public void useCamera(){ StartCamera s = this.findClassLoader().loadClass("StartCamera"); s.start(); } private ClassLoader findClassLoader(){ ClassLoader loader = Thread.currentThread().getContextClassLoader(); if(loader==null){ loader = ClassLoader.getSystemClassLoader(); } return loader; }
相关文章推荐
- WordPress设置圆形旋转头像的方法
- Repository模式
- poj3258River Hopscotch【二分】
- java学习笔记-foreach与iterator
- WordPress让文本小工具支持简码
- 修改WordPress后台登录地址,提高安全性
- 卡特兰数
- 奇虎360退出美国股市 12月再曝拟私有化
- Linux id 命令
- WordPress用键盘左右方向键来查看上一篇和下一篇文章
- hdoj--1237--简单计算器(栈模拟)
- 浙江理工校赛
- 嵌入式ARM 中断 IRQ代码编写 基于S5pv210
- PHP的异步并行网络扩展swoole如何使用
- Mysql高并发优化
- git subproject commit xxxxxxxxxxxxxxxxxxxxx -dirty
- hdoj--1237--简单计算器(栈模拟)
- WordPress后台添加友情链接管理功能
- ubuntu下,iptables:unrecognized service
- [SQLServer] 50种方法优化SQL Server数据库查询