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 类加载系统的基础设计。

相关推荐
Leo July1 天前
【Java】Spring Security 6.x 全解析:从基础认证到企业级权限架构
java·spring·架构
星火开发设计1 天前
C++ 数组:一维数组的定义、遍历与常见操作
java·开发语言·数据结构·c++·学习·数组·知识
码道功成1 天前
Pycham及IntelliJ Idea常用插件
java·ide·intellij-idea
消失的旧时光-19431 天前
第四篇(实战): 订单表索引设计实战:从慢 SQL 到毫秒级
java·数据库·sql
それども1 天前
@ModelAttribute vs @RequestBody
java
雨中飘荡的记忆1 天前
深度详解Spring Context
java·spring
Tao____1 天前
JAVA开源物联网平台
java·物联网·mqtt·开源·ruoyi
yqd6661 天前
SpringSecurity的使用
java·spring
仙俊红1 天前
Java Map 家族核心解析
java·开发语言
一嘴一个橘子1 天前
springMvc 接收参数、cookie、header
java