1、JDK8及以前
1.1、层级结构
| 类加载器 | 加载路径/职责 | 实现语言 | 父加载器 |
|---|---|---|---|
| Bootstrap ClassLoader | 加载 JRE/lib/rt.jar、resources.jar 等核心类库 | C++ | 无(顶级加载器) |
| Extension ClassLoader | 加载 JRE/lib/ext 目录下的扩展类库(如 javax.*) | Java | Bootstrap |
| Application ClassLoader | 加载用户类路径(-classpath 或 CLASSPATH 环境变量)的类 | Java | Extension |
1.2、流程
当一个类加载器收到类加载请求时,优先委派给父加载器处理,只有父加载器无法完成加载时,子加载器才会尝试自己加载。
1.3、目的
确保 Java 核心类库的安全性(避免用户自定义类覆盖核心类),同时保证类的唯一性。
2、JDK9+
2.1、变动原因
JDK 9 的双亲委派机制变动源于模块化系统(JPMS)的引入,旨在适配模块化架构、增强封装性和安全性,同时保持向后兼容性。传统双亲委派被模块化委派部分取代,类加载器根据模块归属(如 java.base、java.sql)直接委派给 Bootstrap、Platform 或 Application ClassLoader,以支持模块边界和依赖管理。移除 rt.jar 和 Extension ClassLoader、引入 Platform ClassLoader 优化了类库结构,而未命名模块保留传统双亲委派,确保兼容 CLASSPATH 应用。
2.2、层级结构
| 类加载器 | 加载路径/职责 | 实现语言 | 父加载器 |
|---|---|---|---|
| Bootstrap ClassLoader | 加载核心模块(如 java.base 模块) | C++ | 无(顶级加载器) |
| Platform ClassLoader | 加载非核心标准模块(如 java.sql、java.xml) | Java | Bootstrap |
| Application ClassLoader | 加载用户模块(模块路径)和未命名模块(类路径) | Java | Platform |
2.3、流程
当一个类加载器收到类加载请求时,先判断是否属于命名模块,如果不是,则走双亲委派机制;如果是,则需要按照对应的模块进行加载。
2.4、对比 JDK 8 的关键变化
1、模块化委派:优先根据模块归属选择加载器(Bootstrap、Platform、Application/Custom),取代严格逐级委派。
2、Bootstrap ClassLoader:
- JDK 8:从
rt.jar加载所有核心类。 - JDK 9:改为从模块(如
java.base)加载,rt.jar被废弃。
3、Platform 取代 Extension:
- JDK 8:
Extension ClassLoader从JRE/lib/ext目录加载扩展类。 - JDK 9:
Platform ClassLoader加载标准模块(非核心),ext目录被废弃。
4、Application ClassLoader:
- JDK 8:仅加载类路径(
-classpath)下的类。 - JDK 9:新增模块路径(
--module-path)支持,同时兼容类路径(归为未命名模块)。
5、未命名模块:
- 类路径下的 JAR 包(未声明模块)由
Application ClassLoader加载,仍遵循双亲委派,但需通过--add-reads或--add-opens与其他模块交互。