双亲委派模型【~类加载器】
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()
但是两个方法之间也是有一些细微的差别。。。。。