Java 字节码指令:深入理解 JVM 的执行语言
字节码(Bytecode)是 Java 实现 “一次编写,到处运行” 的核心,它是 Java 源代码编译后的中间代码,由 JVM 解释执行。字节码指令集是 JVM 与程序之间的 “接口”,理解字节码指令不仅能帮助我们深入掌握 JVM 工作原理,还能解释很多 Java 语法的底层实现(如 synchronized、try-finally、i++ 与 ++i 的差异等)。
字节码指令的基本结构
字节码指令由两部分组成:
- 操作码(Opcode):1 字节长度的数字(0~255),代表特定操作(如加载变量、加法运算等)。
- 操作数(Operand):操作码后跟随的 0~ 多个字节,提供操作所需的参数(如局部变量索引、常量池索引、跳转偏移量等)。
例如,iload_1 指令中,iload 是操作码(表示加载 int 类型局部变量),_1 是隐含操作数(表示局部变量表索引为 1)。
字节码指令分类详解
Java 字节码指令按功能分为九类,每类指令对应程序运行中的特定操作。
加载与存储指令:局部变量表与操作数栈的桥梁
这类指令负责在局部变量表(方法内的变量存储区)和操作数栈(指令执行的临时数据区)之间传递数据。
- 加载(Load):从局部变量表或常量池将数据压入操作数栈。
- 存储(Store):从操作数栈将数据弹出并存入局部变量表。
(1)局部变量压栈指令
将局部变量表中的数据压入操作数栈,按类型和索引区分:
- 简化指令:
xload_<n>(x为类型:i/f/l/d/a;n为 0~3),用于索引 0~3 的局部变量(如iload_1加载索引 1 的 int 变量)。 - 通用指令:
xload(如aload),通过显式参数指定索引(用于索引 ≥4 的变量)。
示例:
1 | public void loadDemo(int i, long l, Object obj) { |