Java类加载器之双亲委派机制

 

概念

在学习双亲委派机制之前首先要了解Java类加载器以及类加载过程,参见我的另一篇博客:https://blog.csdn.net/Jhno99/article/details/106296449

Java虚拟机对class文件采用的是按需加载的方式,也就是说,当需要使用该类时才会将它的class文件加载到内存生成class对象。而且加载某个类的class文件时,Java虚拟机采用的是双亲委派模式,即把请求交由父类处理,它是一种任务委派模式。

工作原理

Java类加载器之双亲委派机制_第1张图片

  1. 如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是将这个请求委托给父类的加载器去执行。
  2. 如果父类加载器还存在父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器。
  3. 如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载。

举例来说:

package com.chapter02;

public class StringTest {
    public static void main(String[] args) {
        String str = new String();
        System.out.println(str.getClass().getClassLoader()); //null

        StringTest test = new StringTest();
        System.out.println(test.getClass().getClassLoader());//sun.misc.Launcher$AppClassLoader@18b4aac2

    }
}

但是我在本工程下创建了一个package:java.lang,并在此包下创建了一个String类,从测试结果来看,加载String对象的时候并没有选择本工程下的这个自定义类,而依然选择的java核心类里的String,因为返回结果为null,说明使用的类加载器是BootstrapClassLoader。打个比方:小朋友拿到一个苹果,刚要吃,发现爸爸在这,就问爸爸吃不吃,爸爸拿到之后一看爷爷在这,就问爷爷吃不吃,爷爷拿到一看,哎,刚好是我喜欢吃的,就吃掉了。

       这是为什么呢?

       原因在于,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。自定义String类,但是在加载自定义String类的时候会率先使用引导类加载器加载,而引导类加载器在加载的过程中会先加载jdk自带的文件(rt.jar包中的java\lang\String.class),运行自定义String类中的main方法时报错信息说没有main方法,就是因为加载的是rt.jar包中的String类。这样就可以保证对java核心源代码的保护,这就是沙箱安全机制

Java类加载器之双亲委派机制_第2张图片


      但是,我们可以自己定义一个类加载器来达到加载自定义类的目的,为了避免双亲委托机制,这个类加载器也必须是特殊的。由于系统自带的三个类加载器都加载特定目录下的类,如果我们自己的类加载器加载一个特殊的目录,那么系统的加载器就无法加载,也就是最终还是由我们自己的加载器加载

       test实例所需的类加载器为系统类加载器ApplicationLoader,过程是这样的:StringTest作为自定义类,会向系统类加载器发送类加载请求,但是并不会自己先去加载,而是向上委托,请求最终将到达顶层的启动类加载器,但是该类在 com.chapter02包下,并属于启动类加载器的加载范畴,所以向下委托给扩展类加载器,发现同样不属于扩展类加载器的范畴,继续向下委托到系统类加载器ApplicationLoader,发现满足条件,则使用ApplicationLoader完成类的加载。继续用上面那个比喻:小朋友拿到一个苹果,刚要吃,发现爸爸在这,就问爸爸吃不吃,爸爸拿到之后一看爷爷在这,就问爷爷吃不吃,爷爷拿到一看,哎呀我不喜欢吃苹果,就又还给了爸爸,爸爸也不想吃,就再还给了儿子,儿子最终就把苹果吃掉了。

       关于双亲委派机制,借用网上大佬的一张图来直观了解:

双亲委派机制的优势:

  • 避免类的重复加载。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
  • 保护程序安全,防止核心API被随意篡改,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

你可能感兴趣的:(Java底层原理)