类加载的双亲委派机制

类加载器的双亲委派机制

​ 除了根类加载器之外,其他的类加载器都需要有自己的父加载器。从JDK1.2开始,类的加载过程采用双亲委派机制,这种机制能够很好的保护java程序的安全。除了虚拟机自带的根类加载器之外,其余的类加载器都有唯一的父加载器。比如,如果需要classLoader加载一个类时,该classLoader先委托自己的父加载器先去加载这个类,若父加载器能够加载,则由父加载器加载,否则才有classLoader自己加载这个类。即每个类加载器都很懒,加载类时都先让父加载器去尝试加载,一直到根类加载器,加载不到时自己才去加载。真正加载类的加载器我们叫做启动类加载器。注意,双亲委派机制的父子关系并非面向对象程序设计中的继承关系,而是通过使用组合模式来复用父加载器代码,这种机制如下图所示:

public class ClassLoaderDemo1 {
    public static void main(String[] args) throws Exception{
        //演示类加载器的父子关系
        ClassLoader loader = ClassLoaderDemo1.class.getClassLoader();
        while(loader!=null){
            System.out.println(loader);
            loader = loader.getParent();
        }
    }
}
运行结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1b6d3586

使用双亲委派机制的好处:

1、可以避免类的重复加载,当父类加载器已经加载了该类时,就没有必要子ClassLoader再加载一次。

2、考虑到安全因素,java核心api中定义类型不会被随意替换,假设通过网络传递一个名为java.lang.Object的类,通过双亲委托模式传递到启动类加载器,而启动类加载器在核心Java API发现这个名字的类,发现该类已被加载,并不会重新加载网络传递的过来的java.lang.Object,而直接返回已加载过的Object.class,这样便可以防止核心API库被随意篡改。

//定义一个类,注意包名
package java.lang;

public class MyObject {

}
//加载该类
public static void main(String[] args) {
    Class clazz = MyObject.class;
    System.out.println(clazz.getClassLoader());
}
//输出结果
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.lang

因为java.lang包属于核心包,只能由根类加载器进行加载,而根据类加载的双亲委派机制,根类加载器是加载不到这个MyObject类的(自定义的),所以只能由AppClassLoader进行加载,而这又不是允许的,所以会报出“Prohibited package name: java.lang”(禁止的包名)错误。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值