什么是双亲委派模型?它是如何工作的?代码举例讲解

双亲委派模型是Java类加载器工作的一种机制。它要求除了启动类加载器之外,其他类加载器要先将类加载工作委托给父类加载器,若父类加载器无法完成加载工作,才自己加载该类。

双亲委派模型的工作过程如下:

  1. 当一个类加载器收到类加载请求时,它首先不会自己去加载类,而是将加载任务委托给父类加载器。
  2. 父类加载器检查自己是否有加载过该类,如果有加载过直接返回,否则继续委托给更上级的父类加载器。
  3. 如果最终启动类加载器也没有加载过,则逐级向下为该类加载器寻找可以完成加载工作的类加载器。
  4. 如果没有任何类加载器能完成加载工作,则由最初发出类加载请求的类加载器自行加载该类。

双亲委派模型的作用主要有:

  1. 防止重复加载:当父类已经被加载过,直接使用缓存的数据,不需要重复加载。
  2. 防止篡改:父类装载器加载的类被子类加载器重新定义。
  3. 有序性:父类总是先于子类被加载,类加载器的重写体系与类继承体系的有序性相对应。

来看一个简单例子:

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");
    }
} 

在该程序中:

  1. appLoader首先将加载String类的任务委托给父类加载器extLoader。
  2. extLoader将再次委托给更上一级的类加载器,最终由启动类加载器加载String类。
  3. appLoader和extLoader会将加载到的Class对象缓存,不会重复加载。