【JAVA基础】JVM之类加载--双亲委派机制

目录

      • 1. 类加载的过程
        • 描述:
        • 看图:
        • 解释:
      • 2. 那么类加载器都有哪些呢
      • 3. 双亲委派机制
        • 3.1 双亲委派机制的过程
        • 3.2 图看委派过程
        • 3.3 为什么要设计双亲委派机制
      • 4. 自定义类加载器
        • 4.1 如何定义自己的类加载器?

1. 类加载的过程

描述:

我们写的.java文件通过编译成字节码文件.class文件,然后再通过我们的类加载器:Class Loader,反射以后,类模板存在方法区,把实例化的对象存在堆里;

看图:

在这里插入图片描述
对象的hashcode值

在这里插入图片描述

解释:
  • 从图中我们可以看出,从同一个类模板new出来三个对象(实例化过程)car1、car2、car3,而他们通过car1.hashCode(); car2.hashCode(); car3.hashCode()得到的hashCode码是不一样的(说明通过new关键字得到的对象不一样);
  • 但是通过 car1.getClass();car2.getClass();car3.getClass();得到的类模板是一样的。(说明是从同一个类模板new出来对象)

总结:

  • 对象. getClass()->获得 类模板;
  • 类模板. getClassLoader()->获得 类加载器

2. 那么类加载器都有哪些呢

类加载器主要分为四种:

  • 1.虚拟机自带的加载器
  • 2.根加载器(启动类加载器)(BootstrapClassloader)
  • 3.扩展类加载器(ExtClassloader) (JKD1.8之后为PlatformClassLoader平台类加载器 )
  • 4.应用程序类加载器(AppClassLoader)一般来说,Java 应用的类都是由它来完成加载的

扩展类加载器(Extension ClassLoader)和 应用程序类加载器(Application ClassLoader)是继承自抽象类java.lang.ClassLoader。

需要注意的是:各个类加载器之间是组合关系,并非继承关系

3. 双亲委派机制

那么到底该有哪个类去加载呢 ?所以我们在这引出双亲委派机制;

3.1 双亲委派机制的过程

一句话:向上委派,上面能加载就会加载;

  • 类加载器受到加载类的请求
  • 然后将这个请求向上委托给父类加载器去完成,一直向上委托:
    App -> Platform -> Bootstrap 直至到根加载器-Bootstrap
  • 根加载器Bootstrap会检查是否能加载当前这个类,(比如java.lang包下的所有类,根加载器都能加载);
    • 若能加载就由根加载器来加载这个类,加载到此结束;
    • 若不能加载,则才向下传递 Bootstrap -> Platform -> App直至有加载器来加载,不然就会报错;比如ClassNotFound

一般来说,Java 应用的类都是由AppClassLoader来完成加载的

总结

如果一个类加载器收到了类加载的请求,它首先不会自己尝试去加载这个类,而是把这个请求委派给父类加载器,每一个层次的类加载器都是加此,因此所有的加载请求最终到达顶层的启动类加载器,只有当父类加载器反馈自己无法完成加载请求时,子类加载器才会尝试自己去加载。

3.2 图看委派过程

在这里插入图片描述

从上图中我们就更容易理解了:

当一个.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。

如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理也会先检查自己是否已经加载过,如果没有再往上。

注意这个类似递归的过程,直到到达Bootstrap classLoader之前,都是在检查是否加载过,并不会选择自己去加载。直到BootstrapClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException

那么有人就有下面这种疑问了?
为什么要有这种机制?

3.3 为什么要设计双亲委派机制

这种设计的好处:

  • 可以确保安全性。
    如果有人想替换系统级别的类:如String.java,篡改它的实现。双亲委派机制可以保证所有的Java类库都是由启动类加载器加载Bootstrap classLoader,从一定程度上防止了危险代码的植入;
  • 可以避免重复加载
    当父亲已经加载了该类的时候,就没有必要让子加载器再加载一次;

面试常问
问: 比如我们自己重新定义一个完全和String同包名的类: java.lang.String类,那么此时jdk加载的是系统自己的String还是我们的String?

答案:当然是系统自己的String类, 也就是说:我们自己写的java.lang.String的类,是不可以替换调JDK本身的类。
为什么呢?虽然和双亲委派机制有关系,但不是非常的准确。因为双亲委托派机制是可以打破的,我们完全可以自己写一个classLoader来加载自己写的java.lang.String类,但是我们会发现也不会加载成功;
真正的原因:
因为针对java.*开头的类,jvm的实现中已经保证了必须由Bootstrap classLoader ,也就是我们的根加载器来加载。

具体描述:
在加载某个类时,优先使用父类加载器加载。如果我们自定义了java.lang.String这个类, 那么该自定义String类使用的加载器应是是AppClassLoader,根据双亲委派原理, AppClassLoader加载器的父类为ExtClassLoader,所以这时加载String使用的类加载器是ExtClassLoader, 但是类加载器ExtClassLoader在jre/lib/ext目录下没有找到String.class类。 然后使用ExtClassLoader父类的加载器BootStrap, 父类加载器BootStrap在jre/lib目录的rt.jar找到了String.class,将其加载到内存中。而jre/lib目录下的 String类 就是我们jdk自己的类。

4. 自定义类加载器

问: 既然JVM已经提供了默认的类加载器,为什么还要自已来定义类加载器呢?

答: 因为Java中提供的默认ClassLoader,只加载指定目录下的jar和class,如果我们想加载其它位置的类或jar时,比如:我们想要加载网络上的一个.class文件,加载到内存之后,我们想要调用这个类中的方法实现自己的业务逻辑。在这样的情况下,默认的ClassLoader就不能满足我们的需求了,所以需要定义自己的ClassLoader。

4.1 如何定义自己的类加载器?

定义自已的类加载器分为两步:

  • 继承java.lang.ClassLoader

  • 重写父类的findClass方法

问: 为什么只重写findClass方法?

答: 因为JDK已经在loadClass方法中帮我们实现了ClassLoader搜索类的算法,当在loadClass方法中搜索不到类时,loadClass方法就会调用findClass方法来搜索类,所以我们只需重写该方法即可。

但是,如没有特殊的要求,一般不建议重写loadClass搜索类的算法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/311801.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8 + openVINO 多线程数据读写顺序处理

多线程数据读写顺序处理 一个典型的生产者-消费者模型,在这个模型中,多个工作线程并行处理从共享队列中获取的数据,并将处理结果以保持原始顺序的方式放入另一个队列。 多线程处理模型,具体细节如下: 1.数据:数据里必…

Java学习,一文掌握Java之SpringBoot框架学习文集(4)

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

GBASE南大通用SQL API 中的 SQL

ESQL 产品为GBASE南大通用数据库 GBase 8s SQL API(应用程序编程接口)。 GBase 为 C 编程语言产生 SQL API。 下图展示 SQL API 产品如何工作。您编写您在其中将 SQL 语句处理作为可执行代码的源 程序。嵌入式 SQL 预处理器处理您的源程序,它…

【QML COOK】- 008-自定义属性

前面介绍了用C定义QML类型,通常在使用Qt Quick开发项目时,C定义后端数据类型,前端则完全使用QML实现。而QML类型或Qt Quick中的类型时不免需要为对象增加一些属性,本篇就来介绍如何自定义属性。 1. 创建项目,并编辑Ma…

Qt 6之六:Qt Designer介绍

Qt 6之六:Qt Designer介绍 Qt Designer是一个可视化的用户界面设计工具,用于创建Qt应用程序的用户界面,允许开发人员通过拖放和布局来设计和创建GUI界面。 Qt 6之一:简介、安装与简单使用 https://blog.csdn.net/cnds123/articl…

作用域与作用域链

作用域与作用域链 一、什么是作用域 作用域就是一个独立的代码区域,域内的变量不会暴露到外部,外部无法访问,也就是说具有隔离性。 function outFun() {var inVariable "内层变量2"; } outFun(); // inVariable 的作用域仅在函…

matlab绘图修改坐标轴数字字体大小及坐标轴自定义间隔设置

一、背景 在matlab使用plot函数绘图后,生成的图片坐标轴数字字体大小及间隔可能并不符合我们的要求,因此需要自定义修改,具体方法如下 二、修改坐标轴数字字体大小 只需添加以下命令即可: set(gca,FontName,Times New Roman,F…

echarts -- 柱状图之柱状条如何显示白色侧阴影且鼠标移入时高亮

有个图表是要求柱状条的右下侧显示一个白色的侧阴影,一直没找到合适的方法, 加border或者shadowColor都达不到需求的效果。 因为柱状图 中series里可以包含多组数据,有几组就代表一个系列中有几个数据。这就代表series里要写七组数据。 对于上…

你了解计算机网络的发展历史吗?

1.什么是计算机网络 计算机网络是指将一群具有独立功能的计算机通过通信设备以及传输媒体被互联起来的,在通信软件的支持下,实现计算机间资源共享、信息交换或协同工作的系统。计算机网络是计算机技术与通信技术紧密结合的产物,两者的迅速发展…

电阻如何读取阻值

前言:大家经常见到的贴片电阻上的丝印有纯数字、数字与R组合、数字与除R之外的字母组合的,但大家知不知道这样的标注与贴片电阻的i精度相关?同一个阻值因为精度不同,标注也会不同。例如封装为0805的贴片电阻,丝印473和…

STL-list的使用简介

目录 ​编辑 一、list的底层实现是带头双向循环链表 二、list的使用 1、4种构造函数(与vector类似)​编辑 2、迭代器iterator 3、容量(capicity)操作 4、element access 元素获取 5、增删查改 list modifiers 6、list的迭…

【计算机组成原理】-指令系统

🎵1.指令的发展 🌈1.1基础概念 计算机的程序是由一系列的机器指令组成的。指令就是要计算机执行某种操作的命令。从计算机的层次结构来说,有微指令,机器指令和宏指令之分。微程序中用到微指令,属于硬件,而…

Fluids —— MicroSolvers DOP

目录 Gas SubStep —— 重复执行对应的子步 Switch Solver —— 切换解算器 Gas Attribute Swap —— 交换、复制或移动几何体属性 Gas Intermittent Solve —— 固定时间间隔计算子解算器 Gas External Forces —— 计算外部力并更新速度或速度场 Gas Particle Separate…

D3121是什么?主要有哪些特点呢?为什么可以应用在车载音响系统上

D3121 是一块对地能动冲放大器集成电路,该电路能有效消除由线 路电阻所引起的问题及噪声。所需外围电容小,便于设计时小型化的同 时可靠性不降低。广泛应用于车载音响系统内。 D3121 系列采用 DIP8 、 SOP8 、 SIP8 的封装形式封装。 主要特点&#…

面试算法115:重建序列

题目 长度为n的数组org是数字1~n的一个排列,seqs是若干序列,请判断数组org是否为可以由seqs重建的唯一序列。重建的序列是指seqs所有序列的最短公共超序列,即seqs中的任意序列都是该序列的子序列。 例如,如果数组org为…

python绘制热力图-数据处理-VOC数据类别标签分布及数量统计(附代码)

前言 当你需要统计训练数据中每个类别标签有多少,并且想知道坐标中心分布在图像的位置信息时,你可以利用一下脚本进行计算! 步骤 要绘制热力图来分析VOC数据的分布统计,可以按照以下步骤进行: 数据处理&#xff1…

移动通信系统关键技术多址接入MIMO学习(8)

1.Multiple-antenna Techniques多天线技术MIMO,从SISO到SIMO到MISO到如今的MIMO; 2.SIMO单发多收,分为选择合并、增益合并;SIMO,基站通过两路路径将信号发送到终端,因为终端接收到的两路信号都是来自同一天…

计算机速成课Crash Course - 18. 操作系统

今天继续计算机速成课Crash Course的系列讲解。 更多技术文章,全网首发公众号 “摸鱼IT” 锁定 -上午11点 - ,感谢大家关注、转发、点赞! 计算机速成课Crash Course - 17. 集成电路&摩尔定律 18. 操作系统 1940,1950 年代的电脑&#…

rime中州韵小狼毫 词组注释 滤镜

在rime中州韵小狼毫 联想词组 滤镜一文中,我们通过Filter滤镜功能配置了联想词组的功能,这使得我们在输入一些关键词汇时,可以联想补充一些附加的词组,例如我输入“手机”,就可以联想补充对应的手机号,如下…

Kali Linux —— 漏洞分析工具

Cisco-torch与Global Exploiter专攻Cisco漏洞 一、Cisco 工具 Kali 有许多工具,比如信息收集工具、密码爆破工具等等,还有一些可用于攻击 Cisco 路由器的工具。Cisco-torch就是这样,用于大规模扫描、指纹识别和利用的工具之一。 打开终端控…