ClassLoader.getSystemClassLoader() 返回系统类加载器(AppClassLoader),负责加载 CLASSPATH 下的类和资源,是 JDK 启动时创建的默认应用类加载器,通常为 sun.misc.Launcher$AppClassLoader(JDK 8 及以前)或 jdk.internal.loader.ClassLoaders$AppClassLoader(JDK 9+)。

ClassLoader.getSystemClassLoader() 返回的是 Java 应用的默认类加载器,即系统类加载器(System ClassLoader),它负责加载 CLASSPATH 指定路径下的类(包括 JAR 包和目录中的 class 文件)。这个加载器是应用启动时由 JVM 自动创建的,通常为 sun.misc.Launcher$AppClassLoader(JDK 8 及以前)或 jdk.internal.loader.ClassLoaders$AppClassLoader(JDK 9+)。
系统类加载器的作用范围
它主要加载以下三类资源:
- 用户编写的主类(即
main方法所在类) - 所有位于
-cp或CLASSPATH环境变量指定路径下的类和资源 - 未被启动类加载器(Bootstrap)和扩展类加载器(Extension)加载的、且符合双亲委派模型“下沉”条件的类
获取方式与典型使用场景
调用方式非常直接:
ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
常见用途包括:
- 动态加载当前 classpath 下的类:
systemLoader.loadClass("com.example.MyService") - 获取资源文件(如配置文件):
systemLoader.getResource("config.properties") - 作为自定义 ClassLoader 的父加载器,确保遵循双亲委派机制
注意事项与常见误区
需要注意几个关键点:
- 该方法返回的不一定是最终加载你当前类的加载器——你的类可能由自定义 ClassLoader 加载,此时
getClass().getClassLoader()才是真实加载者 - 在模块化环境(JDK 9+)中,如果类属于命名模块,系统类加载器可能无法直接访问模块内封装的资源,需配合
Module::getResourceAsStream - 不能用它加载 Bootstrap 或 Extension 路径下的类(如
java.lang.String),这些类由更高层级加载器负责,且不可见
与当前类加载器的区别
不要混淆这两个概念:
-
ClassLoader.getSystemClassLoader()是全局唯一的系统级加载器实例 -
this.getClass().getClassLoader()或MyClass.class.getClassLoader()返回的是**实际加载该类的 ClassLoader**,可能是系统加载器,也可能是 Web 容器(如 Tomcat)的自定义加载器、OSGi Bundle 类加载器等
多数普通 Java SE 程序中二者相同;但在复杂容器或框架中,往往不同。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











