共计 1223 个字符,预计需要花费 4 分钟才能阅读完成。
类加载器
类与类加载器
判断类是否“相等”
任意一个类,都由 加载它的类加载器 和这个 类自身 一起确立其在 Java 虚拟机中的唯一性,每一个类加载器,都有一个独立的类名称空间。
因而,比拟两个类是否“相等”,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即便这两个类来源于同一个 Class 文件,被同一个虚拟机加载,只有加载它们的类加载器不同,那么这两个类就必然不相等。
这里的“相等”,包含代表类的 Class 对象的 equals()
办法、isInstance()
办法的返回后果,也包含应用 instanceof 关键字做对象所属关系断定等状况。
加载器品种
零碎提供了 3 品种加载器:
- 启动类加载器(Bootstrap ClassLoader):负责将寄存在
<JAVA_HOME>\lib
目录中的,并且能被虚拟机辨认的(仅依照文件名辨认,如 rt.jar,名字不合乎的类库即便放在 lib 目录中也不会被加载)类库加载到虚拟机内存中。 - 扩大类加载器(Extension ClassLoader):负责加载
<JAVA_HOME>\lib\ext
目录中的所有类库,开发者能够间接应用扩大类加载器。 - 应用程序类加载器(Application ClassLoader):因为这个类加载器是 ClassLoader 中的
getSystemClassLoader()
办法的返回值,所以个别也称它为“零碎类加载器”。它负责加载用户类门路(classpath)上所指定的类库,开发者能够间接应用这个类加载器,如果应用程序中没有自定义过本人的类加载器,个别状况下这个就是程序中默认的类加载器。
当然,如果有必要,还能够退出本人定义的类加载器。
双亲委派模型
什么是双亲委派模型
双亲委派模型是形容类加载器之间的档次关系。它要求除了顶层的启动类加载器外,其余的类加载器都该当有本人的父类加载器。(父子关系个别不会以继承的关系实现,而是以组合关系来复用父加载器的代码)
工作过程
如果一个类加载器收到了类加载的申请,它首先不会本人去尝试加载这个类,而是把这个申请委派给父类加载器去实现,每一个档次的类加载器都是如此,因而所有的加载申请最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈本人无奈实现这个加载申请(找不到所需的类)时,子加载器才会尝试本人去加载。
在 java.lang.ClassLoader 中的 loadClass
办法中实现该过程。
为什么应用双亲委派模型
像 java.lang.Object 这些寄存在 rt.jar 中的类,无论应用哪个类加载器加载,最终都会委派给最顶端的启动类加载器加载,从而使得不同加载器加载的 Object 类都是同一个。
相同,如果没有应用双亲委派模型,由各个类加载器自行去加载的话,如果用户本人编写了一个称为 java.lang.Object 的类,并放在 classpath 下,那么零碎将会呈现多个不同的 Object 类,Java 类型体系中最根底的行为也就无奈保障。
本文由 mdnice 多平台公布