讲师中心 微信公众号
AI工具推荐 视频效率加速

什么是Java中的双亲委派机制_保证类加载安全的面向对象设计

小伟同学_8162

小伟同学_8162

发布时间:2026-02-26 11:44:03

|

550人浏览过

|

来源于php中文网

原创

双亲委派机制是类加载器间的协作约定,确保核心类由BootstrapClassLoader加载以避免替换;它不提供加密或字节码校验,也非自动安全开关。

什么是java中的双亲委派机制_保证类加载安全的面向对象设计

双亲委派机制不是Java的“安全开关”,而是类加载器之间的协作约定

它不自动防止恶意代码,也不加密或校验字节码;它的作用是通过固定加载顺序,让核心类(比如 java.lang.String)只能由 BootstrapClassLoader 加载,避免被用户自定义类加载器替换——这才是“安全”的实际含义。

常见错误现象:NoClassDefFoundError 或 ClassCastException 在模块间传递对象时突然出现,往往是因为两个类加载器各自加载了同名类,JVM 视为不同类型。

  • 所有自定义类加载器必须重写 loadClass() 时先调用 parent.loadClass(name),不能直接覆盖默认逻辑
  • 想绕过双亲委派?只有在 findClass() 阶段自己读取字节码并调用 defineClass(),但 loadClass() 里仍要保留委托链
  • OSGi、Tomcat、Spring Boot 的 LaunchedURLClassLoader 都是显式打破双亲委派的典型,但它们各自实现了更细粒度的隔离规则,不是简单“禁用”

为什么 Thread.getContextClassLoader() 经常成为破环双亲委派的入口

很多框架(如 JDBC、JAXB、SLF4J)依赖线程上下文类加载器去加载用户提供的实现类,而这个加载器通常是 AppClassLoader 或自定义加载器,它和当前类的加载器(可能是 BootstrapClassLoader)不在同一条委托链上。

使用场景:你写了一个数据库驱动 com.example.MyDriver,放在 WEB-INF/lib 下,但 java.sql.DriverManager 是 Bootstrap 加载的,它必须通过 Thread.currentThread().getContextClassLoader() 去找你的驱动类。

立即学习“Java免费学习笔记(深入)”;

Java调试
Java调试

通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。 术语注解 JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议) remote JVM:远程 Java 虚拟机 step through code:代码单步调试(步入 / 步过 / 步出调试) inspect variables:变量查看 / 变量检视 stac

下载
  • 不要在静态初始化块或 ClassLoader.getSystemClassLoader() 中硬编码加载业务类——它可能找不到你放的 jar
  • Web 应用中,ServletContext.getClassLoader() 和 Thread.currentThread().getContextClassLoader() 通常一致,但不能假设永远相等
  • Spring Boot 的 LaunchedURLClassLoader 把 BOOT-INF/classes 和 BOOT-INF/lib 加入自己的路径,但它仍把 parent 设为 AppClassLoader,所以对 java.* 还是委托上去

defineClass() 和 findClass() 的分工容易混淆

defineClass() 是 JVM 提供的本地方法,负责把字节数组转成 Class 对象,它不做任何验证,也不触发链接;findClass() 是模板方法,由子类实现“从哪读字节码”,然后交给 defineClass() 处理。

错误写法:loadClass() 里直接 new 字节数组再 defineClass(),跳过了委托,也绕过了双亲委派检查。

  • 正确流程:重写 findClass(String name) → 读取字节码 → 调用 defineClass(name, b, off, len) → 返回 Class
  • defineClass() 不会解析常量池、不校验签名,这些在后续链接阶段才做;如果字节码非法,会在 resolveClass() 或首次使用时抛 VerifyError
  • 自定义类加载器若需热替换,必须确保旧 Class 实例已无引用,否则 defineClass() 生成的新类无法被 GC,容易 OOM

模块系统(JPMS)下双亲委派基本失效,但替代机制更严格

JDK 9+ 引入模块后,ClassLoader 不再是唯一类来源,ModuleLayer 和 Configuration 控制哪些模块能看见哪些包。此时 loadClass() 可能返回 ClassNotFoundException,不是因为没委托,而是模块未导出或未读取。

典型报错:java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlRootElement —— 不是类加载器问题,是 java.xml.bind 模块默认不开启,且未加到 --add-modules。

  • 模块路径(--module-path)上的 jar 不进 AppClassLoader,而是由 ModuleClassLoader 管理,它不参与传统双亲委派
  • Class.forName("xxx") 默认使用当前类的类加载器,不是上下文类加载器;跨模块反射需显式用 Module.addOpens()
  • Spring Boot 2.3+ 默认排除 javax.* 相关 starter,就是为适配 JPMS 的模块拆分,不是“兼容性补丁”

真正难处理的,是双亲委派与模块系统的交界处:比如一个模块内定义了服务接口,另一个模块提供实现,而类加载器链和模块读取关系不一致,这时 ServiceLoader 就可能找不到实现类——这已经不是“要不要委托”的问题,而是“谁有权限看到谁”的问题。

热门AI工具

更多
SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4823

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

991

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1269

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6841

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3543

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6820

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

9481

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1290

2024.04.29

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn