【【JVM知识总结-10】类加载器】【JVM知识总结-1】JVM内存模型
【JVM知识总结-2】HotSpot虚拟机对象
【JVM知识总结-3】垃圾收集策略与算法
【JVM知识总结-4】HotSpot垃圾收集器
【JVM知识总结-5】内存分配与回收策略
【JVM知识总结-6】JVM性能调优
【JVM知识总结-7】类的文件结构
【JVM知识总结-8】类的加载时机
【JVM知识总结-9】类加载的过程
【JVM知识总结-10】类加载器
类与类加载器
判断类是否“相等”
任意一个类,都是加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都有一个独立的类名称空间。
因此,比较两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那么这两个类就必定不相等。
这里的“相等”,包括代表类Class对象的equals()
方法,isInstance()
方法的返回结果,也包括使用instanceof
关键字做对象所属关系判定等情况。
加载器种类
系统提供了3中类加载器:
- 启动类加载器(Bootstrap ClassLoader):负责将存放在
目录中的,并且能被虚拟机识别的(仅按照文件名识别,如rt.jar,名字不符合的类库即使放在lib目录中也不会被加载)类库加载到虚拟机内存中。\lib - 扩展类加载器(Extension ClassLoader):负责加载
\lib\ext目录中的所有类库,开发者可以直接使用扩展类加载器。 - 应用程序类加载器(Application ClassLoader):由于这个类加载器是
ClassLoader
中的getSystemClassLoader()
方法的返回值,所以一般也称它为“系统类加载器”。它负责加载用户类路径(classpath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
双亲委派模型 什么是双亲委派模型
双亲委派模型是描述类加载器之间的层次关系。它要求除了顶层的启动类加载器外,其余的类加载器必须有自己的父类加载器。(父子关系一般以继承的方式实现,而是以组合关系来复用父加载器的代码)
工作过程
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求都应该传送到顶层的启动类加载器中,只有当父类加载器反馈自己无法完成这个类加载请求(如:找不到需要的类)时,子加载器才会尝试自己去加载。
在java.lang.ClassLoader中的loadClass方法中实现该过程。
为什么使用双亲委派机制
像java.lang.Object这些存放在rt.jar中的类,无论使用哪个类加载器加载,最终都会委派给最顶端的启动类加载器加载,从而使得不同加载器加载的Object类都是同一个。
相反,如果没有使用双亲委派机制模型,由各个类加载器自行去加载的话,如果用户自己编写了一个称为java.lang.Object的类,并放在classpath下,那么系统就会出现多个不同的Object类,Java类型体系中最基础的行为也就无法保证。