当前位置: 首页 > news >正文

了解类加载器吗?类加载器的类型有哪些?

一、什么是类加载器(ClassLoader)

类加载器是 Java 虚拟机中的一部分,负责将 .class 文件加载到 JVM 内存中,生成对应的 Class 对象。

Java 程序中所有的类在使用前都必须通过类加载器加载进 JVM,才能被执行。


二、类加载器的作用

  • 加载 .class 文件到内存中。
  • 将字节码转换为 JVM 能识别的 Class 对象。
  • 实现类的 命名空间隔离
  • 支持 模块化开发(如插件机制、自定义业务模块加载)。

三、类加载器的分类(JVM 内置 + 用户自定义)

1. 启动类加载器(Bootstrap ClassLoader)

  • 作用: 加载 JVM 的核心类库,如 java.lang.*java.util.* 等。
  • 加载路径: JAVA_HOME/lib 目录中的类(如 rt.jar)。
  • 实现: 由 C/C++ 实现,是 JVM 的一部分。
  • 特点: 不是 Java 类,不能被直接引用或操作。

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

  • 作用: 加载 Java 扩展类库。
  • 加载路径: JAVA_HOME/lib/ext/ 目录或由 java.ext.dirs 系统变量指定的路径。
  • 父加载器: Bootstrap ClassLoader。
  • 类名: sun.misc.Launcher$ExtClassLoader

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

  • 作用: 加载用户类路径(classpath)下的类文件。
  • 加载路径: 当前应用的 classpath(如 jar 包或类文件所在目录)。
  • 父加载器: Extension ClassLoader。
  • 类名: sun.misc.Launcher$AppClassLoader

4. 自定义类加载器(Custom ClassLoader)

  • 作用: 开发者可以继承 java.lang.ClassLoader 实现自己的加载逻辑。

  • 使用场景:

    • 热部署
    • 模块化(如 OSGi)
    • 插件系统
    • 加密 class 文件
  • 常见方式:

    • 继承 ClassLoader 并重写 findClass() 方法
    • 调用 defineClass() 定义类对象

四、类加载器的层次结构图

┌──────────────────────────┐
│ Bootstrap ClassLoader    │
│ (C++实现, 加载核心类库)     │
└──────────┬───────────────┘↓
┌──────────────────────────┐
│ Extension ClassLoader    │
│ (加载 ext 目录类)          │
└──────────┬───────────────┘↓
┌──────────────────────────┐
│ Application ClassLoader  │
│ (加载classpath下类)        │
└──────────┬───────────────┘↓
┌──────────────────────────┐
│ 自定义 ClassLoader       │
│ (可指定加载路径/策略)     │
└──────────────────────────┘

五、双亲委派机制(Parent Delegation Model)

定义:

类加载器在加载类时,首先会 将加载请求委托给父加载器,由顶层的 Bootstrap 开始查找,只有在父加载器找不到时,才由当前加载器加载。

加载流程:

  1. 当前类加载器收到类加载请求。
  2. 委托给父类加载器。
  3. 如果父类无法加载,才由当前加载器尝试加载。

优点:

  • 避免类的重复加载。
  • 防止用户自定义类覆盖 JDK 核心类(如 java.lang.String)。

举例说明:

public class Test {public static void main(String[] args) {System.out.println(String.class.getClassLoader()); // null(Bootstrap)System.out.println(Test.class.getClassLoader());   // AppClassLoader}
}

六、自定义类加载器示例

public class MyClassLoader extends ClassLoader {@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {byte[] data = loadClassData(name); // 从文件或网络中读取字节数组return defineClass(name, data, 0, data.length);}
}

七、线程上下文类加载器(ContextClassLoader)

定义:

  • 每个线程可以设置自己的类加载器,用于动态加载类或资源。
  • 默认是 Application ClassLoader

用途:

  • 在 Java SPI(Service Provider Interface)中尤为重要。
  • 解决双亲委派带来的灵活性限制。
Thread.currentThread().setContextClassLoader(new MyClassLoader());

八、类加载器相关方法(Java API)

方法说明
loadClass(String name)加载类(会委托给父类)
findClass(String name)查找类(自定义类加载核心)
defineClass(...)将字节数组转为 Class 对象
getParent()获取父加载器
getClassLoader()获取当前类的加载器

九、面试常问点总结

问题要点回答
什么是类加载器?.class 加载进内存,生成 Class 对象。
JVM 有哪些类加载器?启动类、扩展类、应用类、自定义类加载器。
双亲委派模型是什么?加载委托给父加载器,避免重复 & 保证安全性。
如何打破双亲委派?重写 loadClass() 不委托父类。
自定义类加载器的用途?插件、加密、安全、热更新、动态部署等。
http://www.dtcms.com/a/290719.html

相关文章:

  • Java 大视界 -- 基于 Java 的大数据分布式计算在地球物理勘探数据处理与地质结构建模中的应用(356)
  • 鹏鼎控股入职测评综合能力真题SHL测评题库2025年攻略
  • postgresql16.4 配置 数据库主从
  • PyTorch 实现 CIFAR-10 图像分类:从数据预处理到模型训练与评估
  • git bash命令不够完善,想整合msys2该怎么办?
  • 02-UE5蓝图初始的三个节点作用
  • 文娱投资的逆势突破:博派资本的文化旅游综合体战略
  • 阿里云宝塔Linux面板相关操作记录
  • 照片to谷歌地球/奥维地图新增功能:导出 GeoJSON 数据
  • 高级技术【Java】【反射】【注解】【动态代理】
  • c++:父类的析构函数定义为纯虚函数注意事项
  • “专属私有云”或“行业公有云(逻辑隔离的公共云专区)”两种主流部署模式到底有什么区别?政务云不就应该是专属的私有云么?政务云是不是不能混用?
  • 网络编程基础:从 OSI 模型到 TCP/IP 协议族的全面解析
  • 【AI高性能网络解析】第三期:数据快递,海量数据跨广域高效传输技术实践
  • 计算机网络:概述层---计算机网络的组成和功能
  • harbor镜像仓库由原来的v2.11.1版本升级到v2.13.1,数据不丢失
  • Taro 生命周期相关 API 详解
  • HTML整理
  • Lists的分批次操作
  • 安卓第一个项目
  • 信息学奥赛一本通 1576:【例 2】选课 | 洛谷 P2014 [CTSC1997] 选课
  • Netty中CompositeByteBuf的使用
  • 位标志法处理多选字段在数据库中的存储方式 查询效率与扩展性之间的权衡
  • https正向代理 GoProxy
  • 苹果最新系统iOS 17的调试和适配方法 - Xcode 14.3.1 真机调试指南
  • How does Misinformation Affect Large Language ModelBehaviors and Preferences?
  • Spring Boot 集成 RabbitMQ:普通队列、延迟队列与死信队列全解析
  • iOS WebView 调试实战 页面跳转失效与历史记录错乱的排查路径
  • 物流链上的智慧觉醒:Deepoc具身智能如何重塑搬运机器人的“空间思维”
  • 达梦数据库JSON_TABLE使用说明