什么是双亲委派模型
加载器
JVM 提供了三种加载器,分别是启动类加载器,扩展类加载器和应用程序器类加载器,如图所示
- 启动类加载器:负责加载Java_HOME/lib 目录中的类库,或通过-Xbootclasspath参数指定路径中被虚拟机认可的类库
- 扩展类加载器:负责加载Java_HOME/lib/ext目录中的类库,或通过java.ext.dirs系统变量加载指定路径中的类库
- 应用程序类加载器:负责加载用户路径的类库 除了上面三种,我们可以自己通过继承java.lang.ClassLoader实现自定义的类加载器
双亲委派模型
双亲委派机制指一个类在收到类加载请求后不会尝试自己加载这个类,而是把类加载请求向上委派给其父类去完成,其父类在接收到该类加载请求后又会将其委派给自己的父类,以此类推,这样所有的类加载请求都被向上委派到启动类加载器中
双亲委派模型流程
双亲委派模型的优点
1. 使得 Java 类随着它的类加载器一起具有一种带有优先级的层次关系,从而使得基础类得到统一
例如 java.lang.Object 存放在 rt.jar 中,如果编写另外一个 java.lang.Object 并放到 ClassPath 中,程序可以编译通过。由于双亲委派模型的存在,所以在 rt.jar 中的 Object 比在 ClassPath 中的 Object 优先级更高,这是因为 rt.jar 中的 Object 使用的是启动类加载器,而 ClassPath 中的 Object 使用的是应用程序类加载器。rt.jar 中的 Object 优先级更高,那么程序中所有的 Object 都是这个 Object。
2. 避免了多份同样字节码的加载,内存是宝贵的,没必要保存相同的两份 Class 对象
例如 System.out.println() ,实际我们需要一个 System 的 Class 对象,并且只需要一份,如果不使用委托机制,而是自己加载自己的,那么类 A 打印的时候就会加载一份 System 字节码,类 B 打印的时候又会加载一份 System 字节码。而使用委托机制就可以有效的避免这个问题。