双亲委派模型【~类加载器】

双亲委派模型【~类加载器】

1,谈论双亲模型前,咱先了解一下什么是类加载器哈,因为双亲模型源头与之有关。

类加载阶段:虚拟机设计者是这样设计的,“通过一个类的全限定名【绝对路径】来获取该类的二进制字节流”,

~例如:Class.forName("类的全限定名");这个动作是在类加载器的帮助下完成的,也是Java 虚拟机外部去实现的。

● 加载类~首先jvm先找到指定的类,然后通过“类加载器”把类装载到虚拟机上。

【打个比方:咱的小猫咪嗅到鱼罐头后,不会打开鱼罐头,主人过来帮它打开鱼罐头,小猫咪就把罐头鱼吃到肚子里】

~主人帮开鱼罐头,就好比“类加载器”(代码模块)帮jvm装载指定的类。

 

2,从 Java 虚拟机的角度来讲,只存在以下两种不同的类加载器:

    启动类加载器(Bootstrap ClassLoader),使用 C++ 实现,是虚拟机自身的一部分
    其它类的加载器使用 Java 实现,独立于虚拟机,并且全部继承自抽象类 java.lang.ClassLoader。

 

3,类加载器细分:启动类加载器、扩展类加载器、应用类加载器、自定义类加载器

 

 4,双亲委派模型,即定义了jvm加载类时的加载规则而已。类加载器的层次关系,称为类加载器的双亲委派模型

该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。

一言概之,双亲委派模型,其实就是一种类加载器的层次关系
 

所谓双亲委派是指每次收到类加载请求时,先将请求委派给父类加载器完成(所有加载请求最终会委派到顶层的Bootstrap ClassLoader加载器中),

如果父类加载器无法完成这个加载(该加载器的搜索范围中没有找到对应的类),子类尝试自己加载,

如果都没加载到,则会抛出 ClassNotFoundException 异常。

5,为什么要有双亲委派模型的存在?

以“为什么我们不能定义同名的 String 的 java 文件?”为例子说明.

因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要 ClassLoader 再加载一次。
考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义的类型,这样会存在非常大的安全隐患,
而双亲委托的方式,就可以避免这种情况,因为String 已经在启动时就被引导类加载器(Bootstrcp ClassLoader)加载,所以用户自定义的ClassLoader永远也无法加载一个自己写的String,
除非你改变 JDK 中 ClassLoader 搜索类的默认算法。

 

6,两种类的加载方式

通常用这两种方式来动态加载一个 java 类,Class.forName() 与 ClassLoader.loadClass()

 但是两个方法之间也是有一些细微的差别。。。。。

 

参考文章:

《双亲委派模型:大厂高频面试题,轻松搞定~https://blog.csdn.net/yusimiao/article/details/99301293》

《一文搞懂双亲委派模型~https://blog.csdn.net/u013568373/article/details/93995246》

 

posted @ 2021-07-25 10:42  一乐乐  阅读(71)  评论(0编辑  收藏  举报