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

双亲委派模型(Parent-Delegation Model)是Java类加载器的工作机制。它要求除了启动类加载器(Bootstrap ClassLoader)外,其余的类加载器都应该有自己的父类加载器。

它的工作原理是:如果一个类加载器收到了类加载请求,它首先不会自己去尝试加载这个类,而是把该请求委派给父类加载器去完成。每一个层次的类加载器都是如此,只有当父类加载器在自己的搜索范围内无法找到所需类时,才会尝试自己去完成加载工作。

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

  1. 避免类的重复加载:通过委派规则,除非父类加载器无法加载某个类,子加载器否则不会重复加载,从而避免冲突。
  2. 保证核心库的安全:启动类加载器专门用于加载Java核心库,如果其他类加载器可以随意加载这些类,很可能会产生安全漏洞。双亲委派模型可以避免这种情况的发生。
  3. 层次隔离:每一层类加载器都有自己loading的范围,使用双亲委派模型可以很好地实现不同层次的加载器之间的隔离。

来看一个简单例子:我们可以编写两个Java程序来模拟双亲委派模型的工作过程。

public class ParentDelegationModelTest {
    public static void main(String[] args) {
        //启动类加载器加载String类
        String s = "Hello"; 

        //自定义类加载器,它的父类加载器是系统类加载器
        MyClassLoader classLoader = new MyClassLoader();

        //尝试使用自定义类加载器加载String类
        try {
            Class<?> clazz = classLoader.loadClass("java.lang.String");
        } catch (ClassNotFoundException e) {
            //自定义类加载器无法加载String类,需要委派给父类加载器
            System.out.println("需要委派给系统类加载器!"); 
        }
    }
}

class MyClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        //如果调用loadClass方法,就会调用findClass方法进行类加载
        throw new ClassNotFoundException(); 
    }
}

输出:

需要委派给系统类加载器!

我们可以看到,自定义类加载器由于遵循双亲委派模型,并不会重复加载String类,而是委派给父类加载器即系统类加载器去完成加载。

所以,双亲委派模型是Java类加载机制的基石,深入理解其工作原理与作用,可以帮助我们解决程序中出现的各种类加载相关问题。