双亲委派机制的特点

双亲委派机制确保类加载时,首先由顶层的启动类加载器加载,避免内存中出现多份同样的字节码,保护核心API不受篡改。若父加载器无法加载,则子加载器尝试加载。该机制在防止自定义`System`类等核心类被替换方面起到关键作用。自定义类加载器可以绕过委托机制,加载特定目录下的类。
摘要由CSDN通过智能技术生成

双亲委派机制:

image-20200524145050497

1. 原理:

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

如果程序中没有定义过自己的类加载器,一般情况下,应用程序加载类加载器就是这个程序的默认加载器。

2.双亲委派模型的好处

1. 防止内存中出现多份同样的字节码
比如两个类A和类B都要加载System类:

  • 如果不用委托而是自己加载自己的,那么类A就会加载一份System字节码,然后类B又会加载一份System字节码,这样内存中就出现了两份System字节码。
  • 如果使用委托机制,会递归的向父类查找,也就是首选用Bootstrap尝试加载,如果找不到再向下。这里的System就能在Bootstrap中找到然后加载,如果此时类B也要加载System,也从Bootstrap开始,此时Bootstrap发现已经加载过了System那么直接返回内存中的System即可而不需要重新加载,这样内存中就只有一份System的字节码了。

2. 防止内存中出现多份同样的字节码

保护程序安全,防止核心API被随意篡改。

  • 例如:如果我们自己自定义了一个 java.lang.String 的类时,如果没有双亲委派机制的话,那么就会将我们程序中的所有运用到String 类 都会使用成我们自定义的类,那么程序就会崩了。有谱
  • 有了双亲委派机制后,首先应用程序类加载器接收到 java.lang.String 的请求之后,就会把这个请求委派给它的父类加载器,即 拓展类加载器。 拓展类加载器收到请求后,又会委派给它的父类加载器,即 引导类加载器。引导类加载器检查了这个类的 包名为 java.lang,那么引导类加载器就会对 它进行加载,因为java.lang 是 Java 下的核心类库。这时候就不会交给系统类加载器进行加载了。即便我们写了这个类,但它也是一个无效类,从而提高了安全性。

3. 双亲委派模型注意点:

  1. Java虚拟机的第一个类加载器是Bootstrap,这个加载器很特殊,它不是Java类,因此它不需要被别人加载,它嵌套在Java虚拟机内核里面,也就是JVM启动的时候Bootstrap就已经启动,它是用C++写的二进制代码(不是字节码),它可以去加载别的类。

    这也是我们在测试时为什么发现System.class.getClassLoader()结果为null的原因,这并不表示System这个类没有类加载器,而是它的加载器比较特殊,是BootstrapClassLoader,由于它不是Java类,因此获得它的引用肯定返回null。

  2. 委托机制具体含义
    当Java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?

    • 首先当前线程的类加载器去加载线程中的第一个类(假设为类A)。
      注:当前线程的类加载器可以通过Thread类的getContextClassLoader()获得,也可以通过setContextClassLoader()自己设置类加载器。
    • 如果类A中引用了类B,Java虚拟机将使用加载类A的类加载器去加载类B。
    • 还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

4. 能不能自己写个类叫java.lang.System

  • **答案:**通常不可以,但可以采取另类方法达到这个需求。
    **解释:**为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸们能找到的类,儿子就没有机会加载。而System类是Bootstrap加载器加载的,就算自己重写,也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值