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

相关推荐
代码什么用7 小时前
Spring基础使用
java·后端·spring
Su米苏8 小时前
Spring AI 中MCP 与普通 @Tool的区别
java·人工智能·spring
码云数智-园园8 小时前
unique_ptr 还是 shared_ptr?C++ 智能指针选型与内存泄漏实战分析
java·开发语言
老板一杯拿铁8 小时前
Java 异常体系详解:从字节码原理到最佳实践
java
蜗牛互联网8 小时前
Java 17 HttpClient调用文件转写API的超时与失败回退
java·人工智能·后端
晒太羊的猫8 小时前
jvm面试题
jvm
禾小西9 小时前
07丨Redis 哨兵机制:主库故障后,如何恢复服务?
java·开发语言·redis
我不是阵雨9 小时前
JDK 21虚拟线程Pinning陷阱:一文拔钉解困
java·开发语言
小卡车5559 小时前
java反射、自定义注解的应用(自定义分页)
java
BLUcoding10 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom