类加载的基本流程

⭐ 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖

类加载

  • 1. 加载
  • 2. 验证
  • 3. 准备
  • 4. 解析
  • 5. 初始化
  • 6. 双亲委派模型

对于⼀个类来说,它的⽣命周期是这样的:
在这里插入图片描述

1. 加载

“加载”(Loading)阶段是整个“类加载”(Class Loading)过程中的⼀个阶段,它和类加载
Class Loading 是不同的,⼀个是加载 Loading 另⼀个是类加载 Class Loading。

在加载 Loading 阶段,Java虚拟机需要完成以下三件事情:

  1. 通过⼀个类的“全限定名”来获取定义此类的⼆进制字节流
  2. 将这个字节流所代表的静态存储结构转化为⽅法区的运⾏时数据结构
  3. 在内存中⽣成⼀个代表这个类的java.lang.Class对象,作为⽅法区这个类的各种数据的访问⼊⼝

也就是找到.class文件,打开文件,读取文件内容。
当代码中给定某个类的“全限定类名”,比如:java.lang.String,java.util.ArrayList,然后jvm就会根据这个类名在一些指定的目录范围内查找。

2. 验证

验证是连接阶段的第⼀步,这⼀阶段的⽬的是确保Class⽂件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运⾏后不会危害虚拟机⾃⾝的安全。

验证选项:

  • ⽂件格式验证
  • 字节码验证
  • 符号引⽤验证

3. 准备

准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。
⽐如此时有这样⼀⾏代码:

public static int value = 123;

它是初始化 value 的 int 值为 0,⽽⾮ 123

只是分配内存空间,还没有初始化。此时这个空间上的内存的数值,就是全0的。

4. 解析

针对类对象中包含的字符串常量进行处理,进行一些初始化操作。也就是将常量池内的符号引用替换为直接引用

比如:final String s="abc",当字符串常量 s 在编译之后,也会进入 .class 文件,同时在 .class 文件的二进制指令中,也会有一个 s 这样的引用被创建出来。我们知道引用里本质上保存的是一个变量的地址,但在.class文件中,不涉及到内存地址,因此在.class 文件中,s的初始化语句,就会先被设置成一个“文件的偏移量”,通过偏移量,就能找到 “abc” 这个字符串所在的位置,当我们这个类真正被加载到内存中的时候,再把这个偏移量替换回真正的内存地址。

5. 初始化

初始化阶段,Java 虚拟机真正开始执⾏类中编写的 Java 程序代码,将主导权移交给应⽤程序。针对类对象进行初始化,初始化阶段就是执⾏类构造器⽅法的过程。
比如:把类对象中需要的各个属性都设置好;初始化好static成员;执行静态代码块;还可能需要加载一下父类等等。

6. 双亲委派模型

双亲委派模型属于类加载中第一个步骤“加载”过程中的一个环节。它的作用就是根据全限定名找到 .class文件。

解释:类加载器是JVM中的一个模块,而JVM内置了三个类加载器。
当⼀个类加载器收到了类加载的请求,它⾸先不会⾃⼰去尝试加载这个类,⽽是把这个请求委派给⽗类加载器去完成,每⼀个层次的类加载器都是如此,因此所有的加载请求最 终都应该传送到最顶层的启动类加载器中,只有当⽗加载器反馈⾃⼰⽆ 法完成这个加载请求(它的搜索范围中没有找到所需的类)时,⼦加载器才会尝试⾃⼰去完成加载。

在这里插入图片描述
上图类加载的过程(找.class 文件的过程)

  1. 给定一个类的全限定类名,形如java.lang.String
  2. 从Application ClassLoader作为入口,开始执行查找的逻辑
  3. Application ClassLoader,不会立即去扫描自己负责的目录(负责的是搜索项目当前目录和第三方库对应目录)而是把查找的任务,交给它的父亲,Extension Classloader
  4. Extension ClassLoader也不会立即扫描自己负责的目录(负责的是 JDK中一些扩展的库,对应的目录)而是把查找的任务,交给它的父亲BootStrap ClassLoader
  5. BootStrap Classloader,也不想立即扫描自己负责的目录(负责的是标准库的目录), 也想把任务交给它的父亲,结果发现自己没有父亲!因此BootStrap ClassLoader 只能亲自负责扫描标准库的目录
  6. 没有扫描到,就会回到Extension ClassLoader。Extension ClassLoader就会扫描负责的扩展库的目录。如果找到,就执行后续的类加载操作,此时查找过程结束;如果没找到,还是把任务交给孩子来执行
  7. 没有扫描到,就会回到Application ClassLoader。Application ClassLoader就会负责扫描当前项目和第方库的目录。如果找到,就执行后续的类加载操作。如果没找到,就会抛出一个ClassNotFoundException

优点:

  • 避免重复加载类:⽐如 A 类和 B 类都有⼀个⽗类 C 类,那么当 A 启动时就会将 C 类加载起来,那么在 B 类进⾏加载时就不需要在重复加载 C 类了。
  • 安全性:使⽤双亲委派模型也可以保证了 Java 的核⼼ API 不被篡改,如果没有使⽤双亲委派模
    型,⽽是每个类加载器加载⾃⼰的话就会出现⼀些问题,⽐如我们编写⼀个称为 java.lang.Object
    类的话,那么程序运⾏的时候,系统就会出现多个不同的 Object 类,⽽有些 Object 类⼜是⽤⼾⾃⼰提供的因此安全性就不能得到保证了。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

防御保护课程笔记

内容安全 防病毒 过滤技术 密码学

ChatGPT学习第四周

📖 学习目标 ChatGPT实践操作 通过实际操作和练习,加深对ChatGPT功能的理解。 项目:创建一个ChatGPT应用案例 设计一个基于ChatGPT的小项目,将理论应用于实践。 ✍️ 学习活动 学习资料 《万字干货!ChatGPT 从零完…

【计算机网络】五种IO模型与IO多路转接之select

文章目录 一、五种IO模型二、非阻塞IO1.fcntl2.实现函数SetNoBlock3.轮询方式读取标准输入 三、I/O多路转接之select1.初识select2.select函数原型3.socket就绪条件4.select的特点5.select缺点6.select使用案例--只读取数据的server服务器1.err.hpp2.log.hpp3.sock.hpp4.select…

动态规划课堂3-----简单多状态问题(买卖股票最佳时机)

目录 引入: 例题1:按摩师(打家劫舍I) 例题2:打家劫舍II 例题3:删除并获得点数 例题4:粉刷房子 例题5:买卖股票的最佳时机含冷冻 结语: 引入: 相信看到…

使用MyBatisPlus实现向数据库中存储List类型的数据

使用MyBatisPlus实现向数据库中存储List类型的数据 问题描述 建表时,表中的这五个字段为json类型 但是在入库的时候既不能写入数据,也不能查询出数据。 解决方案: 1.首先明确,数据存入的时候是经过了数据类型转化&#xff0c…

软件测试——性能测试

目录 一、性能测试简介 二、性能测试指标 三、性能测试的流程 四、Jmeter简介 五、Jmeter常见测试框架 六、Jmeter录制脚本 七、脚本增强 八、Jmeter脚本参数化 九、断言 十、关联 十一、JDBC请求 十二、分布式测试 十三、性能测试报告 一、性能测试简介…

VSCode上搭建C/C++开发环境(vscode配置c/c++环境)Windows系统---保姆级教程

引言劝退 VSCode,全称为Visual Studio Code,是由微软开发的一款轻量级,跨平台的代码编辑器。大家能来搜用VSCode配置c/c,想必也知道VSCode的强大,可以手握一个VSCode同时编写如C,C,C#&#xff…

外泌体相关基因肝癌临床模型预测——2-3分纯生信文章复现——02.数据格式整理(2)

内容如下: 1.外泌体和肝癌TCGA数据下载 2.数据格式整理 3.差异表达基因筛选 4.预后相关外泌体基因确定 5.拷贝数变异及突变图谱 6.外泌体基因功能注释 7.LASSO回归筛选外泌体预后模型 8.预后模型验证 9.预后模型鲁棒性分析 10.独立预后因素分析及与临床的…

Qt 中Qwidget相关属性

文章目录 1. QWidget 核心属性1.1 enabled1.2 geometry1.2.1 window frame 的影响 1.3 windowTitle1.4 windowIcon1.4.1 qrc的使用 1.5 windowOpacity1.6 cursor1.7 focusPolicy1.8 styleSheet 1. QWidget 核心属性 在 Qt 中, 使⽤ QWidget 类表⽰ “控件”. 像按钮, 视图, 输…

算法 -【二叉搜索树的范围和】

二叉搜索树的范围和 题目示例1示例2 分析代码 题目 给定二叉搜索树的根结点 root,返回值位于范围 [low, high] 之间的所有结点的值的和。 示例1 输入:root [10,5,15,3,7,null,18], low 7, high 15 输出:32 示例2 输入:root …

7、Redis-事务、持久化、内存淘汰机制和过期key处理

目录 一、事务 二、持久化 三、内存淘汰机制 四、过期key处理 一、事务 Redis的事务本质上就是一个批量执行命令的操作。分为三个步骤: 开始事务:multi命令入队:正常输入命令即可执行事务(依次执行命令)&#xf…

【rust】11、所有权

文章目录 一、背景二、Stack 和 Heap2.1 Stack2.2 Heap2.3 性能区别2.4 所有权和堆栈 三、所有权原则3.1 变量作用域3.2 String 类型示例 四、变量绑定背后的数据交互4.1 所有权转移4.1.1 基本类型: 拷贝, 不转移所有权4.1.2 分配在 Heap 的类型: 转移所有权 4.2 Clone(深拷贝)…