Java虚拟机原理解析系列
目录
1.字节码指令集概述
1.1 什么是字节码指令集
Java文件的执行,是要先经过编译,形成Class文件,然后经过加载=》连接=》初始化=》使用 到最后的卸载。
我们编写的JAVA代码,经过编译后会形成Class文件,这是我们都知道的。那么Class文件中的内容是什么呢?
JVM底层是有一套自己的指令集合的,Class文件中的内容,其实就是把我们编写的程序逻辑,用JVM的指令来翻译一遍,这样在使用阶段,JVM就可以直接执行了。
JVM的这套指令,就是字节码指令集。这种指令包括 操作码和操作数,就类似于我们调用一个API的方法名和方法的入参。
1.2 字节码指令的构成
字节码指令=操作码+操作数。
操作码:代表某种特定含义的操作。
操作数:可以理解为操作码 需要的参数。
2. 数据类型与Java虚拟机
字节码指令集,大多数都包含其操作所对应的数据类型。
比如:iload 指令代表从局部变量表中加载int行的数据到操作数栈中1,而fload代表的是加载float类型的数据。
因此,在与数据类型相关的字节码指令中,都有一种操作记忆符标明这个指令是专门操作哪种数据类型的。比如l代表long、s代表short、b代表byte、c代表char等
3. 字节码指令详解
下面列举一下字节码指令集中常见的一些指令
3.1 加载和存储指令
指令作用:将数据从Java虚拟机栈的栈帧中的局部变量表和操作数栈之间来回传输。
指令列表:
- 将局部变量加载到操作数栈:iload、lload、fload、dload等
- 将一个值存储到局部变量表:istore、lstore、fstore等
- 将常量加载到操作数栈:bipush、sipush、ldc等
访问对象的字段或者数组的元素的指令,也同样会与操作数栈传输数据。
还有以下两种情况需要注意:
- 带操作数的指令:
iload_<n>:我们知道,iload指令是从局部变量表加载变量到操作数栈,那加一个_<n>是啥意思呢?它代表一组指令,即iload_0、iload_1、iload_2,它们是
带有操作数的指令,它们表面上没有操作数,实际上操作数都是隐含在指令中的,比如iload_0与iload指令且操作数为0的指令是一个意思。 - 隐含操作数类型的指令:
lconst_<i>:代表加载int型的常量到操作数栈。
更多的加载和存储指令见脚注:
3.2 运算指令
指令作用:用于对两个操作数栈上的值进行运算,并把结果重新放入到栈顶。
指令列表:指令分为两种,对整型运算的指令和对浮点型运算的指令。

3.3类型转换指令
该类指令用于处理JVM数值类型的相互转换。
JVM支持从小范围向大范围的安全转换(无需显示的转换指令):
- int类型转到long、float、double
- long类型转换到float、double
- float转换为 double
窄类型的转换,需要使用字节码指令进行:
i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l 和 d2f。
窄类型的转换存在一些风险:
- 导致结果产生不同的正负号。
- 不同的数量级。
- 导致数值丢失精度。
3.4对象创建与操作
用来创建对象或者数组。
- 创建对象的命令:new
- 创建数组的指令:newarray,anewarray,multianewarray
- 访问类的静态变量:getstatic、putstatic
- 访问成员变量:getfield、putfield
- 加载数组元素到操作数栈:baload、caload、saload、iaload、laload、faload、daload、aaload
- 把操作数栈的值存储到数组元素:bastore、castore、sastore、
iastore、fastore、dastore、aastore - 取数组长度的指令:arraylength
3.5操作数栈指令
直接操作操作数栈
- 指令包括:pop、pop2、dup、dup2、
dup_x1、dup2_x1、dup_x2、dup2_x2 和 swap。
3.6控制转移指令
比如我们代码中写的if…else这种,在JVM中也是有字节码指令与之对应的。
- 条件分支:ifeq、iflt、ifle、ifne、ifgt、ifge、ifnull、ifnonnull等
- 无条件分支:goto、goto_w、jsr、jsr_w、ret
3.7 方法调用和返回指令
调用指令:
- 调用对象的实例方法:invokevirtual
- 调用接口的方法:invokeinterface
- 构造方法、私有方法、父类方法调用:invokespecial
- 调用静态方法:invokestatic
返回指令:
ireturn、lreturn、freturn、dreturn 和 areturn
4. 操作码指令大全

对于局部变量表和操作数栈不熟悉的话见我的另一篇博客 Java虚拟机原理-运行时数据区 ↩︎
本文详细介绍了Java虚拟机(JVM)中的字节码指令集,包括指令集的构成、常见指令的作用及分类,如加载与存储指令、运算指令、类型转换指令等。此外还讲解了与数据类型相关的指令及操作数栈指令。

460

被折叠的 条评论
为什么被折叠?



