双亲委派模型是Java类加载器工作的一种机制。它要求除了启动类加载器之外,其他类加载器要先将类加载工作委托给父类加载器,若父类加载器无法完成加载工作,才自己加载该类。
双亲委派模型的工作过程如下:
- 当一个类加载器收到类加载请求时,它首先不会自己去加载类,而是将加载任务委托给父类加载器。
- 父类加载器检查自己是否有加载过该类,如果有加载过直接返回,否则继续委托给更上级的父类加载器。
- 如果最终启动类加载器也没有加载过,则逐级向下为该类加载器寻找可以完成加载工作的类加载器。
- 如果没有任何类加载器能完成加载工作,则由最初发出类加载请求的类加载器自行加载该类。
双亲委派模型的作用主要有:
- 防止重复加载:当父类已经被加载过,直接使用缓存的数据,不需要重复加载。
- 防止篡改:父类装载器加载的类被子类加载器重新定义。
- 有序性:父类总是先于子类被加载,类加载器的重写体系与类继承体系的有序性相对应。
来看一个简单例子:
public class ParentDelegateModelDemo {
public static void main(String[] args) {
// 应用程序类加载器
ClassLoader appLoader = ClassLoader.getSystemClassLoader();
// 扩展类加载器
ClassLoader extLoader = appLoader.getParent();
// appLoader尝试加载String类
Class<?> stringClass1 = appLoader.loadClass("java.lang.String");
// extLoader尝试加载String类
Class<?> stringClass2 = extLoader.loadClass("java.lang.String");
}
}
在该程序中:
- appLoader首先将加载String类的任务委托给父类加载器extLoader。
- extLoader将再次委托给更上一级的类加载器,最终由启动类加载器加载String类。
- appLoader和extLoader会将加载到的Class对象缓存,不会重复加载。