双亲委派模型
站在Java
虚拟机的角度来看,只存在两种不同的类加载器:
启动类加载器(
Bootstrap ClassLoader
)这个类加载器使用C++语言实现,是虚拟机自身的一部分
其他类加载器
这些类加载器都由
Java
语言实现,独立存在于虚拟机外部,并且全部继承自抽象类java.lang.ClassLoader
站在Java
开发人员的角度看,Java
自JDK1.2
以来一直保持三层类加载器、双亲委派的类加载架构。
启动类加载器(
Bootstrap Class Loader
)这个类加载器负责加载存放在
<JAVA_HOME>\lib
目录,或者被-Xbootclasspath
参数指定的路径中存放的,且是
Java
虚拟机能够识别的类库加载到虚拟机的内存中。启动类加载器无法被Java
程序直接引用,用户在编写自定义类加载器时,如果需要把加载请求委派启动类加载器处理,直接使用
null
即可。扩展类加载器(
Extension Class Loader
)这个类加载器是在类
sum.misc.Launcher$ExtClassLoader
中以Java
代码的形式实现。负责加载<JAVA_HOME>\lib\ext
目录,或者被
java.ext.dirs
系统变量所指定的路径中所有的类库。应用程序类加载器(
Application Class Loader
)这个类加载器是在类
sum.misc.Launcher$AppClassLoader
中以Java
代码的形式实现,由于应用程序类加载器是ClassLoader
类中的getSystemClassLoader()
方法的返回值,所以有些场合也称它为“系统类加载器”。负责加载用户类路径上所有的类库。
JDK9
之前的Java
应用都是由这三类类加载器互相配合完成加载的。用户可以加入自定义的类加载器来进行拓展,典型的如增加除了磁盘位置之外的
Class
文件来源,或者通过类加载器实现类的隔离、重载等功能。
双亲委派模型
双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,首先不会自己尝试加载这个类,而是把
请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都会到达最顶层的
启动类加载器中,只有父加载器反馈自己无法完成这个加载请求时,子加载器才会尝试自己去完成加载。