bootstrap classloader是用c++实现的jvm原生组件,非java类、无父加载器,负责在java运行前加载java.lang.object等核心类,并通过-xbootclasspath等参数指定rt.jar等路径;其存在性由string.class.getclassloader()==null等行为验证。

Bootstrap ClassLoader 不是 Java 类,也不继承 java.lang.ClassLoader,它根本不在 Java 层面存在——而是 JVM 启动时由 C++ 代码直接构建并嵌入运行时系统的原生组件。
为什么必须用 C++ 实现?
启动类加载器要完成 JVM 自身的“自举”(bootstrapping):在任何 Java 代码执行前,它就得把 java.lang.Object、java.lang.Class、java.lang.String 这些最基础的类加载进内存。而这些类的定义,恰恰又依赖于 ClassLoader 的机制本身。如果用 Java 写,就陷入“先有鸡还是先有蛋”的循环。C++ 实现绕过了这个依赖,直接操作内存、解析 ZIP/JAR 文件结构、校验字节码格式,并调用 JVM 内部的类注册接口(如 SystemDictionary::resolve_or_null)完成类的链接与初始化。
它到底加载哪些路径和文件?
默认加载路径不是硬编码在 Java 层,而是在 JVM 启动早期由 C++ 函数逐级拼接生成:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
-
核心来源:
$JAVA_HOME/jre/lib/rt.jar(Java 8 及以前)、modules/java.base(Java 9+ 模块化后)以及resources.jar、charsets.jar等 -
可配置入口:通过 JVM 参数
-Xbootclasspath或-Xbootclasspath/a:(追加)动态覆盖或扩展 -
底层存储结构:HotSpot 中用
SystemProperty::sun_boot_class_path全局变量保存最终路径字符串,再由ClassPathEntry链表管理每个 JAR/目录的元信息
它没有父加载器,但为何能当别人“爸爸”?
Bootstrap ClassLoader 在 JVM 内部被设计为一个“逻辑根节点”,其 C++ 对象(如 HotSpot 中的 BootstrapClassLoaderData)不持有父指针,也不参与 Java 层的 getParent() 调用链。但它在类加载委托流程中被隐式前置:
- 当
ExtensionClassLoader或AppClassLoader收到加载请求,按双亲委派规则向上查时,会主动调用 JVM 内部的find_builtin_class接口,该接口直连 Bootstrap 的 C++ 查找逻辑 - 它不暴露引用,所以
ClassLoader.getSystemClassLoader().getParent()返回null;但这不代表它不存在或没作用——只是它的“父性”由 JVM 原生调度策略保障,而非 Java 对象继承关系
你没法在 Java 里拿到它,但能感知它的边界
虽然无法 new、无法 extends、无法 instanceof,但可以通过行为验证它的存在:
-
String.class.getClassLoader() == null—— 因为java.lang.String由 Bootstrap 加载,返回值被 JVM 强制设为null - 尝试用自定义 ClassLoader 加载
java.lang.System会抛SecurityException或直接失败——JVM 在 native 层拦截了对java.*包的非 Bootstrap 加载请求 - 用
jstat -class观察已加载类统计,其中 “loaded” 数量包含大量java/开头类,它们都归属 Bootstrap 管理范畴
本质上,Bootstrap ClassLoader 是 JVM 的“第一行 C++ 代码”和“最后一道安全闸门”的结合体——它不用 Java 生,却决定所有 Java 类能否活下来。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










