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

类加载器的介绍

好的,我来介绍一下类加载器。

在 Java 虚拟机 (JVM) 中,类加载器 (ClassLoader)是一个核心组件,负责在运行时将 Java 类(.class文件中的字节码)加载到 JVM 的内存中,并将其转换为可被 JVM 执行的Class对象。这个过程称为类加载 (Class Loading)

主要作用

  1. 加载字节码:从不同的来源(如文件系统、网络、JAR 包等)查找并读取类的字节码数据。
  2. 定义类:将字节码数据转换为 JVM 内部的Class对象。
  3. 验证:确保加载的类符合 JVM 规范,不会危害虚拟机安全。
  4. 准备:为类的静态变量分配内存并设置默认初始值。
  5. 解析:将符号引用转换为直接引用(可选步骤,可能在加载阶段之后发生)。
  6. 初始化:执行类的初始化代码(如静态变量赋值和静态代码块)。

类加载器的类型(层次结构)

Java 中的类加载器通常采用一种层次结构(也称为双亲委派模型):

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

    • 最顶层的加载器,由 JVM 自身实现(通常用 C/C++ 编写)。
    • 负责加载 Java 核心类库(如rt.jar,charsets.jar等),位于$JAVA_HOME/lib目录下的核心 JAR 包。
    • 是唯一没有父加载器的加载器。
  2. 扩展类加载器 (Extension ClassLoader)

    • sun.misc.Launcher$ExtClassLoader(或类似实现)实现。
    • 负责加载$JAVA_HOME/lib/ext目录下或由java.ext.dirs系统属性指定的目录中的 JAR 包。这些是 Java 的扩展库。
    • 它的父加载器是启动类加载器。
  3. 应用程序类加载器 (Application ClassLoader / System ClassLoader)

    • sun.misc.Launcher$AppClassLoader(或类似实现)实现。
    • 负责加载用户类路径 (ClassPath) 上的类库,通常是应用程序自身的类以及用户添加到ClassPath下的第三方 JAR 包。
    • 它的父加载器是扩展类加载器。
    • 它是开发者最常接触到的类加载器。
  4. 自定义类加载器 (Custom ClassLoader)

    • 开发者可以继承java.lang.ClassLoader类并重写findClass()方法(通常不推荐重写loadClass()以破坏双亲委派)来实现自己的类加载逻辑。
    • 常见应用场景:
      • 从非标准来源加载类(如网络、数据库、加密文件)。
      • 实现热部署(在不重启 JVM 的情况下重新加载修改后的类)。
      • 实现类隔离(如 Web 服务器为每个 Web 应用使用独立的类加载器,避免类冲突)。
      • 字节码增强(如 AOP、动态代理框架)。

双亲委派模型 (Parent Delegation Model)

这是 Java 类加载器默认采用的工作机制:

  1. 委派:当一个类加载器收到加载类的请求时,它首先不会自己尝试加载,而是将这个请求委派给其父类加载器去完成。
  2. 逐级向上:父类加载器收到请求后,如果它自己还有父加载器,则继续向上委派。这个过程一直传递到最顶层的启动类加载器。
  3. 父优先加载:只有当父类加载器反馈自己无法完成这个加载请求(在其搜索范围内找不到所需的类)时,子类加载器才会尝试自己加载。
  4. 子加载:如果父加载器都无法加载,则由发起请求的子加载器调用自己的findClass()方法去加载。

双亲委派模型的优点

  • 避免重复加载:确保一个类在 JVM 中只被加载一次(由最先加载它的加载器加载)。
  • 安全性:核心 Java 类库(如java.lang.Object)由启动类加载器加载,防止用户自定义一个同名的恶意类被优先加载,从而保护核心 API 的安全。
  • 稳定性:保证了 Java 运行环境的基础类库行为一致。
// 示例:模拟双亲委派过程(伪代码) public Class<?> loadClass(String name) throws ClassNotFoundException { // 1. 检查是否已加载 Class<?> c = findLoadedClass(name); if (c != null) { return c; } // 2. 委派给父加载器 if (parent != null) { try { c = parent.loadClass(name); // 递归调用父加载器的loadClass return c; } catch (ClassNotFoundException e) { // 父加载器找不到,继续向下 } } // 3. 父加载器找不到,尝试自己加载 return findClass(name); // 通常由子类重写 }

打破双亲委派

虽然双亲委派是默认模型,但在某些场景下需要打破它:

  • SPI (Service Provider Interface):如 JDBC、JNDI 等。核心接口在rt.jar中由启动类加载器加载,但具体的服务提供商实现由应用类加载器加载。为了解决这个问题,引入了线程上下文类加载器 (Thread Context ClassLoader)
  • OSGi:模块化热部署框架,每个模块(Bundle)使用独立的类加载器,并允许模块间相互依赖和引用。
  • 热部署:需要重新加载修改后的类而不重启 JVM。

总结

类加载器是 JVM 实现动态加载、链接和初始化类的关键机制。理解其层次结构、双亲委派模型以及自定义加载器的原理,对于深入理解 Java 运行机制、排查类加载相关问题(如ClassNotFoundException,NoClassDefFoundError)、实现特定功能(如热部署、类隔离)都非常重要。

http://www.jsqmd.com/news/143774/

相关文章:

  • 2025年甲醛检测机构推荐,专业甲醛检测个性化定制机构全解析 - 工业推荐榜
  • Open-AutoGLM网页使用全解析:20年经验专家总结的4大核心要点
  • 2025-2026CNAS实验室品牌与CMA实验室建设品牌推荐榜单 - 品牌推荐大师1
  • Chrome的cookie编辑插件EditThisCookie
  • 手机也能跑AutoGLM?一文解锁智谱开源模型本地化配置秘技
  • 2025年口碑不错的猎头公司推荐,猎头实力公司与比较不错的猎头机构全解析 - 工业推荐榜
  • 2025年液压中心架推荐供应商排行榜,RX型重型液压中心架制造商专业测评精选推荐 - myqiye
  • 为什么你的Open-AutoGLM在macOS上跑不起来?90%的人都忽略了这3个核心依赖
  • 2025年上海靠谱AI搜索推广公司排行榜,有实力的AI搜索推广企业推荐 - 工业品牌热点
  • 环境配置还是依赖冲突?,深度剖析Open-AutoGLM运行报错根源
  • 学长亲荐10个AI论文软件,本科生论文写作必备!
  • 2025年双相不锈钢供应商年度排名:行业靠谱服务商推荐有哪些? - 工业品牌热点
  • 手把手教你部署清华智谱 Open-AutoGLM(附完整代码与避坑指南)
  • 国产AI硬件崛起,智谱Open-AutoGLM电脑究竟强在哪里?
  • yolo数据集生成
  • 【AI模型轻量化部署】:Open-AutoGLM手机适配的7大核心要点
  • 编码器(Encoder) / 解码器(Decoder) / 编码器-解码器(Encoder-Decoder)架构
  • 清华智谱 Open-AutoGLM 核心技术揭秘(AutoGLM背后的黑科技)
  • PaddlePaddle生态全景图:你不知道的强大工具链
  • NeurIPS 2025 | AI的“精打细算”之道:AgentTTS 如何用智能体优化计算预算?
  • 学术会议合集
  • ‌测试计划的核心要素:定义与基础框架
  • 宏观布局水质监测 智慧型PH传感器赋能产业升级
  • 为什么顶尖AI团队都在关注Open-AutoGLM的独立?(背后隐藏的3大趋势)
  • 【AI开发避坑宝典】:Open-AutoGLM导入失败的7个真实案例与解决方案
  • 2025行业认可X射线精细结构谱仪实力厂家甄选,专业生产商与优质供货商推荐 - 品牌推荐大师1
  • 毕设分享 基于人工智能的图像分类算法研究与实现
  • Open-AutoGLM macOS配置避坑大全(专家级优化技巧首次公开)
  • 2025别墅岩板品牌TOP5权威推荐:天然vs人造/耐污vs普通怎么选? - mypinpai
  • 百度自研PaddlePaddle为何能成为国产深度学习标杆?