Java 类加载器体系详解

Java 类加载器(ClassLoader)体系详解

Java 类加载器是 Java 运行时环境的重要组成部分,负责动态加载 Java 类到 JVM 内存中。Java 采用分层的类加载机制,主要有以下几种类加载器:

1. Bootstrap ClassLoader (引导类加载器)

特点

  • 最顶层的类加载器,由 C/C++ 实现,是 JVM 自身的一部分
  • 负责加载 Java 核心类库(JAVA_HOME/jre/lib 下的 rt.jar、resources.jar 等)
  • 唯一没有父类加载器的加载器
  • 在 Java 中表现为 null(所以调用 String.class.getClassLoader() 返回 null)

加载路径

  • sun.boot.class.path 系统属性指定的目录
  • 通常包括:
    • %JAVA_HOME%/jre/lib 下的核心 jar 包
    • %JAVA_HOME%/jre/classes 目录(已弃用)

2. Extension ClassLoader (扩展类加载器)

特点

  • sun.misc.Launcher$ExtClassLoader 实现
  • 父加载器是 Bootstrap ClassLoader
  • 负责加载 Java 的扩展库(JAVA_HOME/jre/lib/ext 目录下的 jar 包)
  • 开发者可以将通用 jar 包放在此目录下(不推荐,已逐渐被模块化系统取代)

加载路径

  • java.ext.dirs 系统属性指定的目录
  • 默认是 %JAVA_HOME%/jre/lib/ext 目录

3. Application/System ClassLoader (应用/系统类加载器)

特点

  • sun.misc.Launcher$AppClassLoader 实现
  • 父加载器是 Extension ClassLoader
  • 负责加载应用程序类路径(classpath) 下的类
  • 开发者最常打交道的类加载器
  • 可通过 ClassLoader.getSystemClassLoader() 获取

加载路径

  • java.class.path 系统属性指定的路径
  • 包括:
    • 命令行指定的 classpath
    • JAR 文件的类路径
    • IDE 项目中的 src/main/resources 等目录

4. 自定义类加载器

开发者可以继承 java.lang.ClassLoader 类实现自己的类加载器,常用于:

  • 实现热部署
  • 加载非 classpath 下的类
  • 实现类隔离(如 Tomcat 为每个 Web 应用使用独立的类加载器)

典型实现方式

public class MyClassLoader extends ClassLoader {
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // 自定义类加载逻辑
        byte[] classData = loadClassData(name);
        return defineClass(name, classData, 0, classData.length);
    }
}

类加载器层次关系

Bootstrap ClassLoader (null)
       ↑
Extension ClassLoader
       ↑
Application ClassLoader
       ↑
 自定义 ClassLoader

双亲委派模型

Java 类加载采用双亲委派机制(Parent Delegation Model):

  1. 类加载请求首先交给父加载器处理
  2. 只有父加载器无法完成加载时,子加载器才会尝试加载
  3. 这样可以保证核心类库的安全性(防止用户自定义的类替换 Java 核心类)

加载流程

  1. 检查类是否已加载
  2. 未加载则委托父加载器
  3. 父加载器无法加载时,自己尝试加载

类加载器在模块化系统(Java 9+)中的变化

Java 9 引入模块化系统后:

  • Bootstrap、Extension 和 Application 类加载器仍然存在
  • Extension ClassLoader 改名为 Platform ClassLoader
  • 新增了模块路径(module path)概念
  • 类加载机制更复杂,考虑了模块可见性和访问控制

常见问题排查

  1. ClassNotFoundException

    • 检查类是否在 classpath 中
    • 检查类加载器是否正确
  2. NoClassDefFoundError

    • 类加载成功但依赖的类找不到
    • 常见于运行时缺少依赖
  3. LinkageError

    • 同一个类被不同类加载器加载
    • 常见于容器环境(如 Tomcat)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值