






















package com.example.demo;
public class ClassLoaderExample {
public static void main(String[] args) {
// 1.8及以下ClassLoaderExample sun.misc.Launcher$AppClassLoader@18b4aac2
// 1.9+ ClassLoaderExample jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
System.out.println("ClassLoaderExample " + ClassLoaderExample.class.getClassLoader());
// 1.8及以下:ClassLoaderExample getParent sun.misc.Launcher$ExtClassLoader@4c873330
// jdk9+ ClassLoaderExample getParent jdk.internal.loader.ClassLoaders$PlatformClassLoader@26a1ab54
System.out.println("ClassLoaderExample getParent " + ClassLoaderExample.class.getClassLoader().getParent());
// 1.8及以下 ClassLoaderExample getParent null
// jdk9+ ClassLoaderExample getParent getParent null
System.out.println("ClassLoaderExample getParent getParent " + ClassLoaderExample.class.getClassLoader().getParent().getParent());
// 1.8及以下 null
// jdk9+ null
System.out.println("String " + String.class.getClassLoader());
// 1.8及以下 Exception in thread "main" java.lang.NullPointerException
// jdk9+ Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.ClassLoader.getParent()" because the return value of "java.lang.Class.getClassLoader()" is null at
// com.example.demo.ClassLoaderExample.main(ClassLoaderExample.java:18)
System.out.println("String getParent " + String.class.getClassLoader().getParent());
}
}
Java 的类加载器是分层级的,主要有三种类加载器(JDK 8 及以前):
java.lang.*。ClassLoader 的子类实例),因此在 Java 层获取不到它的引用(表现为 null)。jre/lib/ext/ 目录下的类。sun.misc.Launcher$ExtClassLoader 实例。classpath 下的类。sun.misc.Launcher$AppClassLoader 实例。System.out.println("ClassLoaderExample " + ClassLoaderExample.class.getClassLoader());
输出类似于:
ClassLoaderExample sun.misc.Launcher$AppClassLoader@18b4aac2
说明当前类是由应用类加载器加载的。
System.out.println("ClassLoaderExample getParent " + ClassLoaderExample.class.getClassLoader().getParent());
输出:
ClassLoaderExample getParent sun.misc.Launcher$ExtClassLoader@4c873330
AppClassLoader 的父类是 ExtClassLoader,正确无误。
System.out.println("ClassLoaderExample getParent getParent " + ClassLoaderExample.class.getClassLoader().getParent().getParent());
输出:
ClassLoaderExample getParent getParent null
nullExtClassLoader 的父类是 Bootstrap ClassLoader。getParent() 时,如果父加载器是 Bootstrap,就会返回 null。👉 换句话说:
ExtClassLoader.getParent() = BootstrapClassLoader → null in Java
所以你看到的是:
AppClassLoader.getParent() = ExtClassLoader
ExtClassLoader.getParent() = BootstrapClassLoader → null
| 类加载器 | 类名 | getParent() 的结果 |
|---|---|---|
| 应用类加载器 | sun.misc.Launcher$AppClassLoader |
返回 ExtClassLoader |
| 扩展类加载器 | sun.misc.Launcher$ExtClassLoader |
返回 null(实际是 Bootstrap) |
| 引导类加载器 | JVM 内部实现(非 Java 对象) | 无法用 Java 代码直接引用,getParent 为 null |
好的,我们来系统性、严谨地讲解一下 Java 9 模块系统(Project Jigsaw) 引入之后,类加载器机制的变化 —— 特别是与模块(module)系统结合之后的差异。
Java 9 引入了 模块系统(Module System),目的是:
java.base, java.sql, java.xml 等)。我们回顾下 JDK 8 及以前的类加载器结构:
BootstrapClassLoader (C++实现,加载核心类库)
↑
ExtClassLoader (Java实现,加载jre/lib/ext下类库)
↑
AppClassLoader (Java实现,加载classpath中的类)
ExtClassLoader 被废弃。BootstrapClassLoader -> 加载 java.base 等核心模块
↑
PlatformClassLoader -> 加载 JDK 提供的其他模块(例如 java.sql)
↑
AppClassLoader -> 加载用户模块(即 classpath 或 modulepath 中的应用模块)
PlatformClassLoader 替代了原来的 ExtClassLoader。你可以通过以下方式访问:
ClassLoader platformClassLoader = ClassLoader.getPlatformClassLoader();
并通过查看其层级:
System.out.println("PlatformClassLoader: " + platformClassLoader);
System.out.println("PlatformClassLoader parent: " + platformClassLoader.getParent());
它的父类仍然是 BootstrapClassLoader(Java 中表现为 null)。
模块系统不仅组织代码包,还与类加载器紧密相关:
| 模块位置 | 类加载器 |
|---|---|
java.base 等核心模块 |
BootstrapClassLoader |
java.sql 等平台模块 |
PlatformClassLoader |
| 用户定义模块 | AppClassLoader |
System.out.println("String.class loader: " + String.class.getClassLoader()); // null(Bootstrap)
System.out.println("java.sql.Driver.class loader: " + java.sql.Driver.class.getClassLoader()); // PlatformClassLoader
System.out.println("你自己的类 loader: " + YourClass.class.getClassLoader()); // AppClassLoader
Java 9 引入模块系统后,对于 setAccessible(true) 等反射操作增加了限制,默认情况下不能访问其它模块中未开放的 package。
你需要:
--add-opens 参数;opens 或 exports。| Java 版本 | 类加载器结构变化说明 |
|---|---|
| Java 8及以前 | Bootstrap → Ext → App |
| Java 9及以后 | Bootstrap → Platform → App(Ext废弃) |
ExtClassLoader。此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。