JDK9后,类加载机制,相较于JDK8以前的双亲委派机制的改变
JDK9类加载机制中的模块优先委派规则解析
一、背景:JDK9的模块化系统(JPMS)
JDK9引入了模块化系统(Java Platform Module System, JPMS),将JDK核心类库拆分为多个模块(如java.base、java.sql等)。这一变化影响了类加载机制,传统的三层类加载器(启动类加载器、扩展类加载器、应用类加载器)在JDK9中演进为:
- 平台类加载器(PlatformClassLoader):替代原扩展类加载器,负责加载JDK的平台模块
- 应用类加载器(AppClassLoader):负责加载应用程序的类路径(classpath)资源
- 启动类加载器(BootstrapClassLoader):仍负责加载最核心的模块(如
java.base)
二、模块优先的类加载委派规则
在JDK9之前,类加载遵循双亲委派模型:类加载器收到请求后先委派给父加载器,父加载器无法加载时才自己处理。
而JDK9的新规则是:平台类加载器和应用类加载器在委派给父加载器前,会先判断目标类是否属于某个系统模块。若属于,则优先由对应模块的加载器处理,而非直接遵循传统的双亲委派顺序。
三、具体流程解析
- 类加载请求触发:当平台类加载器(或应用类加载器)收到加载类
X的请求时 - 模块归属判断:检查
X是否属于某个系统模块(通过模块描述符module-info.class定义) - 模块加载器优先:
- 若
X属于模块M,则由负责加载模块M的加载器处理(通常是平台类加载器或启动类加载器) - 若不属于任何模块,则按传统双亲委派模型,先委派给父加载器(平台类加载器的父加载器是启动类加载器)
- 若
- 父加载器委派:若模块加载器无法处理,再按传统流程向上委派
四、案例说明:以java.lang.String类为例
假设应用程序尝试加载java.lang.String类,流程如下:
- 加载器接收请求:应用类加载器(
AppClassLoader)收到加载java.lang.String的请求 - 模块归属检查:
java.lang.String属于java.base模块(JDK核心模块)java.base模块由启动类加载器(BootstrapClassLoader) 负责加载
- 模块加载器优先处理:
- 应用类加载器不会直接委派给父加载器(平台类加载器),而是先判断该类属于
java.base模块 - 直接委托给负责
java.base模块的启动类加载器加载
- 应用类加载器不会直接委派给父加载器(平台类加载器),而是先判断该类属于
- 启动类加载器加载:成功加载
java.lang.String,返回类对象
五、另一个案例:自定义模块与应用类的加载
假设存在以下场景:
- 模块
com.example.util(位于JDK平台模块路径)定义了类com.example.util.Utils - 应用程序定义了类
com.example.app.App,依赖com.example.util.Utils
加载流程:
- 应用类加载器加载
App类,发现依赖Utils - 检查
Utils的模块归属:Utils属于com.example.util模块(平台模块)- 该模块由平台类加载器(PlatformClassLoader) 负责加载
- 平台类加载器处理:
- 平台类加载器先检查
com.example.util模块是否已加载 - 若未加载,则加载该模块并实例化
Utils类
- 平台类加载器先检查
- 依赖注入完成:
App类成功引用Utils类
六、模块优先规则的意义
- 强化模块化隔离:确保系统模块中的类只能由对应加载器加载,避免应用程序通过类路径覆盖核心类
- 优化加载效率:直接定位模块加载器,减少不必要的父加载器委派
- 支持模块化部署:使JDK自身模块与应用模块的加载逻辑更清晰,符合JPMS设计目标
七、与JDK8双亲委派模型的对比
| 场景 | JDK8双亲委派模型 | JDK9模块优先规则 |
|---|---|---|
加载核心类(如String) |
应用类加载器→扩展类加载器→启动类加载器 | 应用类加载器先判断模块归属,直接委派给启动类加载器 |
| 加载平台模块类 | 无模块概念,扩展类加载器加载 | 平台类加载器优先加载对应模块类 |
| 加载应用类 | 应用类加载器自行处理(父加载器无法加载) | 若不属于模块,按传统流程委派 |
八、总结
JDK9的类加载机制在传统双亲委派模型基础上,增加了模块归属判断的优先级:当类属于某个系统模块时,优先由负责该模块的加载器处理。这一改动是JPMS模块化设计的核心体现,既保证了系统模块的隔离性,又优化了类加载流程。理解这一机制有助于在模块化开发中避免类加载冲突,尤其是在处理自定义模块与JDK核心模块的依赖关系时。

浙公网安备 33010602011771号