Java技术八股Day19

类加载器详解

类加载器核心概念

类加载器是负责加载类的对象,核心作用是将 Java 类的二进制字节流(.class 文件)动态加载到 JVM 中,在内存生成对应的 Class 对象作为访问入口。ClassLoader 是抽象类,除 BootstrapClassLoader 由 C++ 实现外,其余类加载器均由 Java 实现并继承自该类。每个类都持有加载它的类加载器引用,数组类由 JVM 自动创建,其类加载器与元素类型的类加载器一致(基本类型数组无类加载器)。类加载器遵循 "按需加载" 和 "相同二进制名称类仅加载一次" 规则,已加载的类会存储在自身的 classes 集合中。

JVM 内置类加载器

JVM 内置三种类加载器,按层级从高到低为:

  • BootstrapClassLoader(启动类加载器):顶层加载器,C++ 实现,无父加载器,加载 JDK 核心类库(% JAVA_HOME%/lib 目录下的 rt.jar 等)及 -Xbootclasspath 指定路径的类,获取其引用时返回 null。
  • ExtensionClassLoader(扩展类加载器):加载 % JRE_HOME%/lib/ext 目录及 java.ext.dirs 系统变量指定路径的类,父加载器为 BootstrapClassLoader。
  • AppClassLoader(应用程序类加载器):面向用户,加载当前应用 classpath 下的类,父加载器为 ExtensionClassLoader,是用户自定义类的默认加载器。Java9 后扩展类加载器更名为平台类加载器,除 java.base 等核心模块由启动类加载器加载外,其他模块由其加载。

自定义类加载器

自定义类加载器需继承 ClassLoader 抽象类,推荐重写 findClass () 方法(不打破双亲委派模型),仅在父类加载器无法加载时,通过该方法自定义字节流获取逻辑(如解密加密的 .class 文件);若需打破双亲委派模型,则需重写 loadClass () 方法,改变 "先委派父类加载" 的默认流程。自定义类加载器的父加载器可通过构造函数指定,可是内置类加载器或其他自定义类加载器,通过组合关系复用父加载器逻辑。

双亲委派模型

(1)核心定义

双亲委派模型是 JDK 推荐的类加载机制,要求除顶层启动类加载器外,所有类加载器都有父加载器,类加载请求会先委派给父加载器执行,仅当父加载器无法加载时,子加载器才尝试自己加载。此处 "双亲" 并非指两个父加载器,而是层级委派关系,父子关系通过组合实现而非继承。

(2)执行流程
  1. 类加载时先检查当前类是否已加载,已加载则直接返回;
  2. 未加载则将请求委派给父加载器,最终传递至 BootstrapClassLoader;
  3. 父加载器尝试加载,若成功则返回 Class 对象,失败则子加载器调用 findClass () 方法自行加载;
  4. 若子加载器也无法加载,抛出 ClassNotFoundException 异常。
(3)核心好处
  • 避免类重复加载:同一类由父加载器统一加载,确保类的唯一性;
  • 保护核心 API:核心类(如 java.lang.Object)由 BootstrapClassLoader 加载,且 ClassLoader 的 preDefineClass () 方法禁止加载以 "java." 开头的类,防止恶意篡改核心类。

打破双亲委派模型的方式

双亲委派模型非强制性约束,打破方式主要有两种:

  • 重写 loadClass () 方法:自定义类加载器重写该方法,改变 "先委派父加载" 的逻辑,例如 Tomcat 的 WebAppClassLoader,优先加载 Web 应用目录下的类,实现 Web 应用间类隔离;
  • 利用线程上下文类加载器:通过 Thread 的 setContextClassLoader () 设置上下文类加载器,让高层类加载器(如加载 SPI 接口的 BootstrapClassLoader)借助低层类加载器(如加载 SPI 实现的 AppClassLoader)加载类,解决 SPI 接口与实现类加载层级不一致的问题,Spring 等框架常采用此方式加载业务类。
相关推荐
一个心烑2 分钟前
奖项届定获取方式
java
小红的布丁2 分钟前
Reactor 模型详解:单 Reactor、主从 Reactor 与 Netty 思想
android·java·开发语言
weixin_704266059 分钟前
redis 的集群
java·数据库·redis
被摘下的星星10 分钟前
Java的类加载
java·开发语言
真上帝的左手12 分钟前
8. 测试-性能测试-JMeter实战
java·压力测试
cheems952713 分钟前
[SpringMVC] SpringWebMVC常见注解介绍
java·springmvc·注解
me83213 分钟前
【Java】Spring MVC接口执行流程详解:从前端请求到参数封装全解析(前端到底是怎么和后端交互的?)
java·spring·mvc
skilllite作者14 分钟前
SkillLite 多入口架构实战:CLI / Python SDK / MCP / Desktop / Swarm 一页理清
开发语言·人工智能·python·安全·架构·rust·agentskills
niucloud-admin15 分钟前
插件开发——upgrade 插件版本升级
java
vortex515 分钟前
Gradle 从入门到实战
java·gradle