Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

  • JVM

    • JVM概述
    • JVM基础

    • 类加载机制

      • 类的生命周期
      • 类加载器
        • 1. 类加载器的作用
        • 2. 常见类加载器
        • 3. Bootstrap ClassLoader
        • 4. Platform ClassLoader
        • 5. Application ClassLoader
        • 6. 自定义类加载器
        • 7. 类加载器隔离
        • 8. 类加载器层次图
        • 9. 类加载器命名空间
        • 10. loadClass 和 findClass
        • 11. 自定义类加载器流程
        • 12. 开发中常见问题
          • 12.1 为什么 Spring Boot fat jar 也涉及类加载器
          • 12.2 为什么热部署容易内存泄漏
        • 13. Tips 快问快答
        • 14. 总结
      • 双亲委派模型
      • 类初始化顺序
      • 类加载问题与SPI
    • 运行时内存

    • 垃圾回收

    • 执行引擎与优化

    • 工具与问题排查

    • 调优实践与面试

目录

类加载器

类加载器负责把类的字节码加载到 JVM 中。对 JVM 来说,一个类不仅由全限定类名决定,还由加载它的类加载器共同决定。

# 1. 类加载器的作用

类加载器主要负责:

  • 定位 class 字节码。
  • 读取 class 字节流。
  • 定义 Class 对象。
  • 参与类隔离。

同一个类文件,如果由两个不同类加载器加载,在 JVM 中会被认为是两个不同的类。

# 2. 常见类加载器

Java 8 中常见类加载器:

  • Bootstrap ClassLoader:启动类加载器。
  • Extension ClassLoader:扩展类加载器。
  • Application ClassLoader:应用类加载器。

Java 9 引入模块系统后,扩展类加载器被平台类加载器替代:

  • Bootstrap ClassLoader。
  • Platform ClassLoader。
  • Application ClassLoader。

# 3. Bootstrap ClassLoader

启动类加载器负责加载核心类库,例如 java.lang.String、java.lang.Object 等。

它通常由 C/C++ 实现,在 Java 层面获取父加载器时可能显示为 null。

System.out.println(String.class.getClassLoader()); // null

# 4. Platform ClassLoader

平台类加载器负责加载平台模块中的类。

Java 9 之后,模块系统改变了类库组织方式,Platform ClassLoader 承担了原扩展类加载器的一部分角色。

# 5. Application ClassLoader

应用类加载器负责加载应用 classpath 或 module path 中的类。

System.out.println(MyClass.class.getClassLoader());

普通业务类通常由应用类加载器加载。

# 6. 自定义类加载器

可以继承 ClassLoader 实现自定义加载逻辑。

常见场景:

  • 插件系统。
  • 热部署。
  • 类隔离。
  • 加密 class 解密加载。
  • 字节码动态生成。

一般重写 findClass,而不是直接重写 loadClass,以避免破坏双亲委派。

# 7. 类加载器隔离

类的唯一性由类加载器和类全限定名共同决定。

Class identity = ClassLoader + package.ClassName

这解释了为什么有时明明类名一样,却会出现:

ClassCastException: A cannot be cast to A

因为两个 A 可能由不同类加载器加载。

# 8. 类加载器层次图

Bootstrap ClassLoader
        ▲
        │
Platform ClassLoader
        ▲
        │
Application ClassLoader
        ▲
        │
Custom ClassLoader

这里的父子关系不是 Java 继承关系,而是加载委派关系。一个类加载器通常保存父加载器引用,加载类时先委派给父加载器。

# 9. 类加载器命名空间

JVM 判断两个类是否相同,需要同时看:

类全限定名 + 定义类加载器

例如:

loaderA 加载 com.example.User
loaderB 加载 com.example.User

这两个 User 在 JVM 中不是同一个类,即使字节码完全一样。

这也是插件系统能实现依赖隔离的基础。

# 10. loadClass 和 findClass

自定义类加载器时常见两个方法:

方法 作用
loadClass 类加载入口,默认实现包含双亲委派逻辑
findClass 当前加载器真正查找并定义类的位置

一般建议重写 findClass,不要轻易重写 loadClass。如果重写 loadClass,很容易破坏双亲委派,导致核心类安全或依赖隔离问题。

# 11. 自定义类加载器流程

loadClass("com.example.Plugin")
 │
 ├─ 检查是否已经加载
 │
 ├─ 委派父加载器加载
 │
 └─ 父加载器失败
      └─ findClass()
          ├─ 读取字节码
          ├─ defineClass()
          └─ 返回 Class 对象

# 12. 开发中常见问题

# 12.1 为什么 Spring Boot fat jar 也涉及类加载器

Spring Boot 可执行 jar 中依赖嵌套在 jar 内部,标准 URLClassLoader 不能直接按普通目录读取所有嵌套 jar,因此 Spring Boot 使用自己的加载机制处理嵌套 jar。

# 12.2 为什么热部署容易内存泄漏

热部署通常通过丢弃旧类加载器、创建新类加载器实现。如果旧类加载器仍被线程、静态变量、ThreadLocal、驱动注册表等引用,它加载的所有类都无法卸载。

# 13. Tips 快问快答

Q:String.class.getClassLoader() 为什么是 null?

A:String 由 Bootstrap ClassLoader 加载,启动类加载器在 Java 层通常用 null 表示。

Q:类加载器父子关系是继承吗?

A:不是,是委派关系。子加载器持有父加载器引用。

Q:为什么同名类不能互相强转?

A:如果由不同类加载器定义,它们在 JVM 类型系统中就是不同类型。

Q:自定义类加载器最常见用途是什么?

A:插件化、热部署、类隔离、加密 class 加载、动态字节码生成。

# 14. 总结

类加载器不仅负责加载类,还负责类隔离和命名空间管理。理解类加载器,是理解应用服务器、插件化、SPI、框架冲突、热部署和 classpath 问题的前提。

上次更新: 2026/06/24, 16:03:01
类的生命周期
双亲委派模型

← 类的生命周期 双亲委派模型→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式