jdk 9 前 extension classloader 与 jdk 9+ platform classloader 本质是同一职责的延续,均负责加载 jdk 自带的非核心但属平台级的类库(如 java.logging、jdk.crypto.cryptoki),不加载核心类(由 bootstrap 加载)和用户类(由 appclassloader 加载)。

Extension ClassLoader(JDK 9 前)和 Platform ClassLoader(JDK 9+)本质是同一职责在不同版本的延续:它们负责加载 JDK 自带的、非核心但属于平台级的类库,既不是最底层的运行时基础(那是 Bootstrap 的事),也不处理用户业务代码(那是 AppClassLoader 的事)。
它加载哪些具体路径的类
在 JDK 8 及更早版本中,Extension ClassLoader 默认加载 $JAVA_HOME/jre/lib/ext 目录下所有 JAR 包中的类。这个目录是“扩展机制”的体现,允许开发者把通用工具类(如加密、XML 处理等)放进去,无需显式加到 CLASSPATH 就能被自动识别。
JDK 9 引入模块系统后,/ext 目录被废弃,Extension ClassLoader 本身也被标记为废弃(仍保留以兼容旧代码),其职能由 Platform ClassLoader 接替。Platform ClassLoader 不再依赖物理路径,而是加载 JDK 内置平台模块,比如 java.logging、java.naming、jdk.crypto.cryptoki 等——这些模块位于 $JAVA_HOME/jmods/ 或通过 JVM 内部模块图解析获得。
它不加载什么(关键边界)
-
不加载 rt.jar 或核心类:像
java.lang.Object、java.util.ArrayList这类基础类,由 Bootstrap ClassLoader 加载(C++ 实现,Java 层不可见);即使你把String.class放进/ext,它也不会被 Extension/Platform 加载——双亲委派会先让 Bootstrap 找,而它早就加载过了。 -
不加载用户 classpath 下的类:你用
java -cp myapp.jar MyApp启动的类,或通过CLASSPATH指定的 JAR,全部归 AppClassLoader 管;Platform ClassLoader 完全无视这些路径。 -
不加载应用自定义模块或第三方库:Maven 引入的
commons-lang3、Spring 的spring-core,哪怕打包进模块路径(--module-path),只要不是 JDK 自带模块,就不归它管。
它在委派链中的实际位置
它是 Bootstrap 和 AppClassLoader 的中间层:
- JDK 8:Bootstrap → Extension → AppClassLoader
- JDK 9+:Bootstrap → Platform → AppClassLoader(注意:Platform 的父加载器仍是 Bootstrap,不是 Extension)
这意味着,当你调用 MyClass.class.getClassLoader() 得到的是 AppClassLoader,它的 getParent() 返回 Platform ClassLoader,再往上就是 null(Bootstrap)。你可以用这段代码验证:
while (cl != null) {
System.out.println(cl);
cl = cl.getParent();
}
为什么这个边界设计很重要
它保障了 Java 平台的分层可信模型:
- Bootstrap 加载最可信的核心,无法被 Java 代码篡改;
- Platform 加载 JDK 提供的“可选但受信”能力,比如安全服务、国际化支持,由 JVM 统一管控;
- AppClassLoader 隔离用户代码,防止业务类污染平台行为。
例如,如果你自己写了个 java.util.Base64 类并放在 classpath 中,AppClassLoader 会尝试加载它,但双亲委派会让 Platform(甚至 Bootstrap)先响应——最终加载的仍是 JDK 自带版本,避免类型冲突和安全风险。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











