java类加载器层级需通过getclassloader()和getparent()逐级追溯,启动类加载器在java层表现为null;jdk9后extclassloader被移除,platformclassloader成为appclassloader父加载器,其父为null。

Java 类加载器的层级结构不能直接“打印”出来,但可以通过获取当前类、系统类或任意类的 ClassLoader 实例,并逐级向上追溯其父加载器来观察实际运行时的委托链。核心是理解并利用 getClassLoader() 和 getParent() 方法。
查看当前类的加载器链
每个类对象都可通过 .getClass().getClassLoader() 获取其加载器;该加载器的 getParent() 返回其父加载器,直到为 null(表示已到启动类加载器)。注意:启动类加载器由 C++ 实现,Java 层表现为 null。
- 普通应用类通常由
AppClassLoader(即URLClassLoader子类)加载 - 它父加载器是
ExtClassLoader(扩展类加载器),再往上就是启动类加载器(null) -
String.class.getClassLoader()返回null,因为String由启动类加载器加载
用递归方式打印加载器层级
写一个简单工具方法,传入任意类,输出从该类加载器开始、逐级向上直到 null 的完整链路:
public static void printClassLoader(Class> clazz) {
ClassLoader loader = clazz.getClassLoader();
int level = 0;
while (loader != null) {
System.out.println("Level " + level + ": " + loader);
loader = loader.getParent();
level++;
}
System.out.println("Level " + level + ": Bootstrap ClassLoader (null)");
}
调用示例:printClassLoader(MyClass.class) 或 printClassLoader(String.class),输出会清晰展示委托路径。
区分不同类的加载器差异
不同类可能由不同加载器加载,结果不同:
-
MyClass.class.getClassLoader()→ 通常是AppClassLoader -
ArrayList.class.getClassLoader()→null(JDK 核心类,启动类加载器) -
javax.xml.parsers.DocumentBuilder.class.getClassLoader()→ 可能是ExtClassLoader(旧版 JDK 扩展机制)或AppClassLoader(JDK 9+ 模块化后变化)
注意 JDK 版本与模块系统的影响
JDK 9 引入模块系统后,扩展类加载器被移除,ExtClassLoader 不再使用;平台类(如 java.*)由 BootLoader 加载,其他模块类可能由 PlatformClassLoader(可访问,非 null)加载:
-
ClassLoader.getSystemClassLoader()仍是应用类加载器(AppClassLoader) -
ClassLoader.getSystemClassLoader().getParent()在 JDK 9+ 中返回PlatformClassLoader,不再是null -
PlatformClassLoader的getParent()才是null(对应启动类加载器)
不复杂但容易忽略:加载器链反映的是运行时实际委托关系,不是固定不变的继承图;调试时建议结合 getClass().getClassLoader() 和 getParent() 一步步验证,比查文档更直观可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











