类的唯一性
类是由类加载进行加载的。对于任意一个类,在Java虚拟机中的唯一性是由加载它的类加载器和这个类本身共同确定的。每一个类加载器都拥有一个独立的类命名空间。
双亲委派模型(Parents Delegation Model)
经典的Java类加载器双亲委派模型。系统提供启动类加载器(Bootstrap Class Loader)、扩展类加载器(Extension Class Loader)和应用程序类加载器(Application Class Loader)。用户可以根据需求自定义类加载器。
双亲委派模通常使用组合(Composition)关系复用父加载器。是组合关系,不是继承关系!
如果一个类加载器收到类加载的请求,它首先不会自己去加载这个类,而是把这个请求委派给自己的父类加载器,每一个层次的类加载器都是这样,因此所有的类加载请求最终都会传到启动类加载器,只有当父类加载器无法完成加载请求时,子类加载器才会尝试自己去加载类。
- 启动类加载器:C++语言实现的。负责加载<JAVA_HOME>\lib目录和参数-Xbootclasspath指定路径存放的类文件,并且类文件要是虚拟机能够识别的类库。
- 扩展类加载器:Java语言实现的。加载<JAVA_HOME>\lib\ext目录中,或被java.ext.dirs系统变量指定路径的类库。
- 应用程序类加载器:Java语言实现的。加载用户类路径上的所有类库。如果程序中没有自定义过自己的类加载器,则这个就是默认的类加载器。
破坏双亲委派模型
历史上因为种种原因会出现破坏双亲委派模型的应用,例如JNDI服务和OSGi。Java9引入模块化系统一定程度上破坏了双亲委派模型。
当平台及应用类加载器收到类加载请求时,在委派给父类加载器加载前,要先判断该类是否能够归属到某一个系统模块中,如果可以找到这样的归属关系,就要优先委派给负责这个模块的加载器进行加载。
如下图JDK9的双亲委派模型架构图,类加载器可能不再将类加载委派给其父类加载器。
JDK9双亲委派模型架构图
网友评论