当前位置: 首页 > news >正文

JAVA程序的类加载器的底层和双亲委派机制的原理

类加载器的作用就是加载.class文件,比方说new关键字

类加载器有很多个

  1. 虚拟机自带的加载器

  2. 启动类(根)加载器

  3. 平台类加载器,java9之后就替代了扩展类加载器。

    • 注意java8及以前是叫做扩展类加载器在 Java 8 及更早版本中,用于加载位于%JAVA_HOME%/jre/lib/ext目录(或由java.ext.dirs系统属性指定的目录)下的 JAR 文件,这些 JAR 文件通常包含了对 Java 核心类库的扩展功能,比如一些第三方的安全、加密相关扩展。

  4. 应用程序加载器

我们通过下面的代码来看一下各个加载器是层层递进的形式进行加载的

当我们new一个对象的时候就会发生层层递进的情况,这里面有一个很重要的东西叫做双亲委派机制

package java.lang;
​
public class String {public String toString() {return "Hello";}//双亲委派机制public static void main(String[] args) {String s = new String();System.out.println(s.toString());}
}

当我们运行一个类之前,实际上是一层一层的进行寻找,找到了才执行,比方说首先从AppClassLoader也就是应用加载器向上进行查找就是到达平台类加载器,到达之后先进行寻找是否存在这个类,找不到的话再向上寻找也就是bootstrap类加载器,假如说还是无法找到,这个时候就会往下寻找,与前面相反,当我们到达应用类加载器的时候,才能够找到并执行。

上面的代码就是到达bootstrap类加载器的时候就找到了String类所以就会出现报错

当我们换一种命名方式的情况下就会正常运行

package com.JvmTest.TestjVMDemo1;
​
public class Test {public String toString() {return "Hello";}public static void main(String[] args) {Test s = new Test();System.out.println(s.toString());}
​}

执行结果也是正确的。

双亲委派机制(Parent Delegation Model)是 Java 类加载器(ClassLoader)的核心工作原则,用于保证类的唯一性、安全性和稳定性。其核心逻辑可概括为:

“子加载器收到类加载请求时,优先委派给父加载器处理,只有父加载器无法完成时,子加载器才尝试自己加载。”

✅ 示例: 应用程序类加载器(AppClassLoader)加载用户类 com.example.MyClass 时: AppClassLoader → 委派 → ExtClassLoader → 委派 → BootstrapClassLoaderBootstrapExt 均无法加载,AppClassLoader 才从 classpath 加载。

Java 类加载器采用 树形层级结构,分为四层:

  1. Bootstrap ClassLoader(启动类加载器)

    • 加载路径<JAVA_HOME>/jre/lib(如 rt.jar

    • 特点:唯一无父类的加载器,由 C++ 实现(Java 中显示为 null)。

  2. Extension ClassLoader(扩展类加载器)

    • 加载路径<JAVA_HOME>/jre/lib/ext

    • 父类Bootstrap(实际由 Bootstrap 加载其自身)。

  3. Application ClassLoader(应用类加载器)

    • 加载路径:用户类路径(classpath

    • 父类Extension ClassLoader

  4. 自定义类加载器

    • 用户继承 ClassLoader 实现,默认父类为 AppClassLoader

📌 注意: 双亲委派中的“双亲”并非继承关系,而是组合关系(子加载器持有父加载器引用)。

http://www.dtcms.com/a/274233.html

相关文章:

  • Bash函数详解
  • 软件开发那些基础事儿:需求、模型与生命周期
  • MySQL锁的分类
  • Linux驱动学习day22(interrupt子系统)
  • spring-boot项目集成spring-ai
  • TCP服务端处理HTT
  • V少JS基础班之第七弹
  • 【Linux】GDB/CGDB 调试器学习笔记
  • 【Git】git的回退功能
  • map数据结构在Golang中是无序的,并且键值对的查找效率较高的原因
  • pyQt基础4(对话框)
  • 力扣 hot100 Day41
  • OS16.【Linux】冯依诺曼体系结构和操作系统的浅层理解
  • 深度学习×第8卷:优化器与训练流程进阶——她开始跑起来,学着一次次修正自己
  • 聊聊AI大模型的上下文工程(Context Engineering)
  • linux网络编程之单reactor模型(一)
  • 渗透测试之木马后门实验
  • 笔记 | 理解C/汇编中的数组元素访问
  • UNIX 域套接字实现本地进程间通信
  • 【React Native】样式、网络请求和Loading
  • Hadoop 用户入门指南:驾驭大数据的力量
  • 【React Native】原生组件
  • Dify 1.5.0,1.5.1,1.6.0 新特性
  • 小旺AI截图×英特尔强强联合:AIPC生态开启智能生产力新纪元
  • C++设计秘籍:为什么所有参数都需类型转换时,非成员函数才是王道?
  • 基于强化学习的智能推荐系统优化实践
  • 继续Java的jpackage模块打包Linux可执行程序(包含第三方非模块化包)
  • 4G Cat.1 时代,如何选对 DTU?
  • IoC 是如何为 Spring 的其他核心功能(如 AOP、事务管理)提供基础支持的
  • openpilot:为您的汽车插上智能驾驶的翅膀