Java Class Loader

本文深入探讨Java中四种类加载器的作用、关系及其在实际应用中的重要性,特别是如何利用Context ClassLoader打破类加载器的委托机制,解决类路径冲突问题。同时介绍了Context ClassLoader在构建线程时的配置方法,以及如何通过它实现更灵活的类加载策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.blogjava.net/clraychen/archive/2008/02/20/180868.html

java中一共有四个类加载器,之所以叫类加载器,是程序要用到某个类的时候,要用类加载器载入内存。 这四个类加载器分别为:bootstrap classloader、extension

classloader、appclassloader和urlclassloader,他们的作用其实从名字就可以大概推测出来了。其中appclassloader在很

多地方被叫做system classloader

bootstrap classloader是在jvm开始运行的时候加载java的核心类,是用

c++编写的,它用来加载核心类库,在jvm源代码中这样写道:

static const char classpathformat[] =

"%/lib/rt.jar:"

"%/lib/i18n.jar:"

"%/lib/sunrsasign.jar:"

"%/lib/jsse.jar:"

"%/lib/jce.jar:"

"%/lib/charsets.jar:"

"%/classes";

extension classloader是用来加载扩展类,即/lib/ext中

的类。

appclassloader用来加载classpath的类,是和我们关系最密

切的类。

urlclassloader用来加载网络上远程的类,暂且不讨论。

它们之间的关系:

1.parent-child,按顺序从大到小。不是简单的继承关系。

2.classloader有个getparent的方法,但是ext classloader调用后得到的是null,bootstrap

是jvm自己的,用户看不到。

3.classloader的委托机制:当等级比较低的classloader要加载某个类的时候,它首先会请求

parent加载器来加载,parent再请求它的parent,比如现在ext要加载了,它往上请求。如果最大的bootstrap找不到,那么boot会叫ext自己找找,ext找不到,是不会让下一级的app去找的,此时就报出

classnotfoundexception

4.类a调用类b,b会要求调用它的类的类加载器来加载它,也就是b会要求加载a的加载器来加载b。这就会有个问题,如果他们在一起,那没关系,肯定某个

classloader会把它们俩都加载好。但是如果a在/lib/ext文件夹中,而b在classpath中呢?

程是这样的,首先加载a,那么一层层上到bootstrap

classloader,boot没找到,

所以ext自己找,找到了,没问题;加载b,因为a调用了b,所以也从bootstrap来找,没找到,然后a的ext

classloader来找还是没找到,但是再也不会往下调用了,于是报出classnotfoundexception。

但是现实生活中有很多应用,比如jdbc核心方法在核心库而驱动在扩展库,是必定在两个地方的,那怎么办呢?要用到context

classloader我们在建立一个线程thread的时候,可以为这个线程通过setcontextclassloader方法来指定一个合适的

classloader作为这个线程的context

classloader,当此线程运行的时候,我们可以通过getcontextclassloader方法来获得此context

classloader,就可以用它来载入我们所需要的class。默认的是system

classloader。利用这个特性,我们可以“打破”classloader委托机制了,父classloader可以获得当前线程的context

classloader,而这个context

classloader可以是它的子classloader或者其他的classloader,那么父classloader就可以从其获得所需的

class,这就打破了只能向父classloader请求的限制了。这个机制可以满足当我们的classpath是在运行时才确定,并由定制的

classloader加载的时候,由system classloader(即在jvm

classpath中)加载的class可以通过context

classloader获得定制的classloader并加载入特定的class(通常是抽象类和接口,定制的classloader中是其实现),例

如web应用中的servlet就是用这种机制加载的.


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值