jvm双亲委派的含义

这个名字感觉和他要干的事情关系不大。

我们编译好的.class文件加载进方法区/元空间 需要用到类加载器,类加载器有很多种,有启动类加载器(Bootstrap ClassLoader),扩展类加载器(Extension ClassLoader),应用程序类加载器(AppClassLoader),每个类都只能用一个加载器加载进来,那某一个类到底是用哪个加载器呢?

各个类加载器加载的类对应如下:

  1. 启动类加载器负责加载 JDK 核心类库(如rt.jar),而Dog类是自定义类,不在其加载路径中,因此加载失败。
    扩展类加载器负责加载jre/lib/ext目录下的扩展类库,Dog类通常也不在此路径,因此加载失败。
    应用程序类加载器负责加载类路径(classpath)上的类,例如开发者编写的Dog类通常存放在项目的classpath下(如src目录编译后的classes文件夹),因此会被 AppClassLoader 成功加载。

当我们加载我们编写的Dog类的时候,jvm并不是直接用应用类加载器去加载,而是用启动类加载器去加载,显然,Dog类不是核心类库,加载不进去,退而采用扩展类加载器加载,当然,Dog也不是扩展类库,所以也加载不到,所以最终会由应用程序加载器加载。

如果我们写了个String 类,jvm采用哪个加载器,也是上面一样的选择过程,但是String类是核心类库里的类(jvm认的是类名,虽然你自己写了个String

类,但是JVM最开始用的是启动类去扫描String,所以会在核心类库扫到了String类,加载的是核心类库的类),所以最终jvm永远也找不到你自己写得这个类,会出现无法加载主类的报错。

如果你想自己写一个String类去替换核心类库的String类,则需要将你写好的String类放到核心类库目录(不建议这么做),则可能被启动类加载器加载。但这是人为修改路径的特殊情况,默认情况下自定义类都由 AppClassLoader 加载。

所以,我们写类名的时候,必须要避开java原有的类名。

这就是所谓的双亲委派机制

Java 的双亲委派机制(Parent Delegation Model)是类加载器(ClassLoader)的核心工作机制,其核心思想是 "先委托父加载器加载,父加载器无法加载时才由子加载器自行加载" 。这一机制确保了类加载的安全性和唯一性。

工作流程

当一个类加载器收到类加载请求时,它不会立即自己去加载,而是先将请求委托给其父类加载器

父类加载器重复这一过程,直到请求传递到顶层的启动类加载器

如果父类加载器能成功加载该类,则返回加载结果

如果父类加载器无法加载(通常是找不到该类),则将请求逐级回传,最终由最初的类加载器尝试加载

双亲委派机制通过层次化的委托模型,既保证了 Java 核心类库的安全,又实现了类加载的灵活性,是 Java 类加载系统的基础设计。

相关推荐
lgcgkCQ几秒前
【AI 转型实战 1】SpringAI 入门:搭建基础大模型对话能力
java·ai·agent·rag·spring ai·mcp·langchain4j
Wang's Blog5 分钟前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友
学到老活到老13 分钟前
第 24 集:配置文件写了 80,Spring Boot 为什么读到 90?
java·后端·spring
tongyiixiaohuang36 分钟前
供应商主数据同步实战:从易快报到金蝶云星空的单一策略落地
java·网络·数据库
鱼宵1 小时前
取集合第一个元素,Java 为什么要写三种写法?
java·windows·python·java21
学长毕设1 小时前
基于SpringBoot的餐厅管理系统-附源码
java·spring boot·后端
刚入门的大一新生2 小时前
Linux-线程互斥
java·开发语言
赵小哥要冲啦2 小时前
社区邻里互助小程序从 0 到 1 复盘:需求拆解与信任机制设计
java·小程序·需求分析
xiaogai_gai2 小时前
采购业务退款单同步实战:从钉钉审批流到金蝶云星空付款单
java·数据库·钉钉
二哈赛车手3 小时前
新人笔记---hermes定时功能设计,具体讲解以及可优化点
java·人工智能·笔记·spring·ai·typescript