前言
双亲委派模型是一个面试经典题目
类加载
当咱们运行 java 程序时,首先须要将 .java 文件通过编译后生成对应 .class 文件,而后由 JVM 来加载.class 文件到内存中。作为开发人员咱们不须要去关怀.class 文件是如何被加载到 JVM 中的,这所有工作都有类加载器去实现。
类的加载过程如图所示:
- 加载,加载分为三步:
1、通过类的全限定性类名获取该类的二进制流;
2、将该二进制流的动态存储构造转为办法区的运行时数据结构;
3、在堆中为该类生成一个 class 对象;
附 jvm 内存结构图。 - 验证:验证该 class 文件中的字节流信息复合虚拟机的要求,不会威逼到 jvm 的平安;
- 筹备:为 class 对象的动态变量分配内存,初始化其初始值;
- 解析:该阶段次要实现符号援用转化成间接援用;
-
初始化:到了初始化阶段,才开始执行类中定义的 java 代码;初始化阶段是调用类结构器的过程;
在第一阶段加载过程中,咱们即能够抉择应用零碎提供的类加载器来实现加载,也能够应用自定义的类加载器来加载。类加载器
在 java 中,类加载器 ClassLoader 有四种
- BootStrapClassLoader: c++ 编写,加载外围库 java.*;
- Extension ClassLoader: java 编写,加载扩大库 javax.*;
- AppClassLoader: java 编写,加载程序目录;
- 自定义 ClassLoader:java 编写,继承自 ClassLoader,定制化加载;
双亲委派模型
加载一个类时,先向上委派,实际上就是查找缓存,是否加载了该类,有则间接返回,没有持续向上。委派到顶层后,缓存中还是没有,则到其加载门路中查找,有则对类进行加载,没有持续向下查找。向上委派到顶层类加载器为止,向下查找到发动加载的类加载器为止。
BootstrapClassLoader 类加载器负责加载 [jdk 根目录]/lib 下的 class 文件。
ExtClassLoader 类加载器负责加载 [jdk 根目录]/lib/ext 下的 class 文件。
AppClassLoader 类加载器负责加载用户自定义 class 类文件。
长处:
1. 虚拟机只有在两个类的门路和类名雷同且加载该类的加载器均雷同的状况下才断定这是一个类。若不采纳双亲委派机制,同一个类有可能被多个类加载器加载,这样该类会被辨认为两个不同的类,互相赋值时会有问题。双亲委派机制能保障多加载器加载某个类时,最终都是由一个确定加载器加载,确保最终加载后果雷同。
2. 避免用户自定义一个外围类,如自定义一个 String 类且门路雷同,通过双亲委派模型,jvm 并不会去加载用户自定义的 String 类,而是去加载特定包下的 String 类。