类加载器的双亲委派模式

原理:
当JVM将Java源码加载为字节码时,类加载器就会加载和初始化字节码文件,将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区中运行的数据结构,在堆中生成一个代表该类的java.lang.Class对象,作为方法区类数据的访问入口,最后这些数据是否能运行,运行结果如何,是由执行引擎Execution engine 来负责。

前面说到过JVM自带的类加载器(ClassLoader)有三种(等级由上至下):

启动类加载器Boostrap(C++编写,不允许开发者直接通过引用操作)、

拓展类加载器Exension (由sun.misc.Launcher$ExtClassLoader代理实现)、

应用程序加载器(AppClassLoder,又称系统类加载器 System ClassLoader 加载当前应用的Class Path的所有类,由sun.misc.Launcher$AppClassLoader代理实现)

除此之外,最后才是用户自定义加载器 ,是用于加载开发人员自己编写的类

而所谓的双亲委派原则是指,当我们用自定义的类通过类加载器实例化对象时,类加载器会向上委托类加载器所加载的类的对象(注意,拓展类加载器和应用程序加载器均继承自java.lang.classloader的抽象类,且他们均是由代理机制实现的,他们之间的关系是平级,不是继承关系,但是作为顶级类加载器BootStrap,由于启动类加载器无法被 Java 程序直接引用,因此 JVM 默认直接使用 null 代表启动类加载器。),而如果这个类对象没有我们定义的某个方法,就会一层一层向上查找其他的类加载器,询问是是否加载过这个类,如果都找不到就会报错ClassNotFoundException,如果找到就直接返回这个已经加载过的类。
代码实现的话是酱紫(这里引用了博主华仔狂战 的代码):

package test;
public class ClassLoaderParentMain {
 
    public static void main(String[] args){
        ClassLoader ClassLoader1 = ClassLoaderParentMain.class.getClassLoader();
        ClassLoader ClassLoader2 = ClassLoader1.getParent();
        ClassLoader ClassLoader3 = ClassLoader2.getParent();
 
        System.out.println(ClassLoader1);
        System.out.println(ClassLoader2);
        System.out.println(ClassLoader3);
    }
}

直观来看是酱紫:
思维图
实际上是酱紫:

调用图

所以 !!!当用户企图篡改JDK源码时!!! 即用户企图自己编写类去替换系统级别的类比如 String.java, 篡改它的实现,但是在这种机制的约束下,这个类已经被Bootstrap类加载器加载过了(而这个顶级类加载器是由C++编写的),从一定程度上防止了代码入侵的问题。
引用图 是酱紫:
流程图

总结:双亲委派机制是一种保护机制,其目的是通过这种层级关可以避免类的重复加载,优先加载类时优先由Bootstrap ClassLoader 、Extension ClassLoader加载,同时保证Java核心库的类型安全,使java核心api中定义类型不会被随意替换

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值