news 2026/5/1 21:45:06

类加载器的介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
类加载器的介绍

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

在 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)、实现特定功能(如热部署、类隔离)都非常重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 10:24:42

数据库期末复习笔记:SQL查询与数据库理论核心知识点总结

数据库期末复习笔记&#xff1a;SQL查询与数据库理论核心知识点总结本文整理自手写笔记&#xff0c;涵盖数据库系统的核心概念、SQL高级查询技巧、关系模型完整性约束、函数依赖与范式理论、事务隔离级别等内容&#xff0c;适合备考数据库课程的同学们快速回顾重点。&#x1f4…

作者头像 李华
网站建设 2026/5/1 17:19:01

Open-AutoGLM网页实战技巧,掌握这6个功能让你效率提升300%

第一章&#xff1a;Open-AutoGLM网页怎么用 Open-AutoGLM 是一个基于大语言模型的自动化网页交互工具&#xff0c;允许用户通过自然语言指令控制浏览器行为&#xff0c;实现网页内容提取、表单填写、页面导航等操作。该工具无需编写复杂脚本&#xff0c;适合非编程背景用户快速…

作者头像 李华
网站建设 2026/5/1 6:37:36

论文写作终极神器:7款AI工具5分钟生成3万字问卷论文!

在学术写作的高压赛道上&#xff0c;大学生、研究生与科研人员面对的是时间紧、任务重、质量要求高的三重挑战。传统写作流程不仅耗时耗力&#xff0c;还在问卷研究、数据分析、引用规范等环节埋下无数坑。本文直接抛出终极清单——7款经过严苛实测的AI论文工具排行榜&#xff…

作者头像 李华
网站建设 2026/5/1 15:29:08

从A2UI到AIGS:JBoltAI如何重塑AI时代的人机交互与系统开发

在数据驱动决策的今天&#xff0c;业务人员的需求越来越灵活&#xff1a;“为什么华东区本月销量下滑&#xff1f;”“分析新产品口碑与销售地域的关联”——这些问题往往需要复合化、场景化的答案&#xff0c;而传统BI工具的固定仪表板、僵硬表格早已难以应对。与此同时&#…

作者头像 李华
网站建设 2026/5/1 2:52:13

手机也能跑AutoGLM?一文解锁智谱开源模型本地化配置秘技

第一章&#xff1a;智谱开源Open-AutoGLM如何配置手机Open-AutoGLM 是智谱推出的开源自动化大语言模型工具&#xff0c;支持在移动端完成轻量化推理与任务编排。将该框架部署至手机端&#xff0c;可实现离线自然语言处理、智能指令执行等功能。环境准备 在配置前需确保手机已满…

作者头像 李华