【【JVM】类加载器与双亲委派模型】类加载器与双亲委派模型
类加载器在加载阶段,会将class文件加载进方法区。有关类加载的全过程,可以先参考我的另外一篇文章类的奇幻漂流——
类加载机制探秘
类加载器的类型类加载器的类型
类加载器有以下种类:
启动类加载器(启动类加载器(Bootstrap ClassLoader))
扩展类加载器(扩展类加载器(Extension ClassLoader))
应用类加载器(应用类加载器(Application ClassLoader)
启动类加载器启动类加载器
内嵌在JVM内核中的加载器,由C++语言编写(因此也不会继承ClassLoader),是类加载器层次中最顶层的加载器。用于加
载java的核心类库,即加载jre/lib/rt.jar里所有的class。由于启动类加载器涉及到虚拟机本地实现细节,我们无法获取启动类加
载器的引用。
扩展类加载器扩展类加载器
它负责加载JRE的扩展目录,jre/lib/ext或者由java.ext.dirs系统属性指定的目录中jar包的类。父类加载器为启动类加载器,但
使用扩展类加载器调用getParent依然为null。
应用类加载器应用类加载器
又称系统类加载器,可用通过 java.lang.ClassLoader.getSystemClassLoader()方法获得此类加载器的实例,系统类加载器也
因此得名。应用类加载器主要加载classpath下的class,即用户自己编写的应用编译得来的class,调用getParent返回扩展类
加载器。
扩展类加载器与应用类加载器继承结构如图所示:
可以看到除了启动类加载器,其余的两个类加载器都继承于ClassLoader,我们自定义的类加载,也需要继承ClassLoader。
双亲委派机制双亲委派机制
当一个类加载器收到了一个类加载请求是,它自己不会先去尝试加载这个类,而是把这个请求转交给父类加载器,每一个层的
类加载器都是如此,因此所有的类加载请求都应该传递到最顶层的启动类加载器中。只有当父类加载器在自己的加载范围内没
有搜寻到该类时,并向子类反馈自己无法加载后,子类加载器才会尝试自己去加载。
ClassLoader内的loadClass方法,就很好的解释了双亲委派的加载模式:
protected Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
//检查该class是否已经被当前类加载器加载过
Class c = findLoadedClass(name);
if (c == null) {
//此时该class还没有被加载
try {
if (parent != null) {
//如果父加载器不为null,则委托给父类加载
c = parent.loadClass(name, false);
} else {