从 Java 虚拟机指令(操作码)集 列表上来看,一共 21 个指令;按照处理数据的类型,合并同类项后,剩下有 nop 、、、、、、、、和等几个指令。下面,按照顺序,对其进行一一讲解。
操作码助记符的首字母一般是有特殊含义的,表示操作码所作用的数据类型: i 代表对 int 类型的数据操作; l 代表 long ; s 代表 short ; b 代表 byte ; c 代表 char ; f 代表 float , d 代表 double ; a 代表 reference。 |
nop根据 Chapter 6. The Java Virtual Machine Instruction Set:nop 来看,就是“Do nothing”,暂时没有找到使用方法。就不做多介绍,后续看到相关资料,再做补充。
const*const 是一个大类,根据不同的操作数类型,又分为、、、和等几个分类。
const 指令主要就是将相关类型的“常量”(与 Java 使用 static final 修饰的“常量”的定义不同,这里是 Java 代码中存在的“直接量”,比如给对象赋值的 `null`等)推送至栈顶。下面对其一一介绍。
aconst_null这里只有 aconst_null ,直接上代码演示:
/ * 字节码示例代码 * * @author D瓜哥 · https://www.diguage.com */ public class Example { / * 操作码 aconst_null 示例 */ public Object testAconst() { return null; } }
使用 javac Example.java 编译,然后使用 javap 来查看编译的结果:
$ javap -c Example
Compiled from "Example.java"
public class Example {
public Example();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."":()V
4: return
public java.lang.Object testAconst();
Code:
0: aconst_null
1: areturn
}
在上述结果中,我们如愿看到了 aconst_null 操作码。从上面的 testAconst 方法的指令来看,是将 null 加载到栈顶,然后返回。与我们的代码是一致的。
对比了 Java 8 与 Java 17 的编译结果。从 javap -c 的输出上来看,两者没有差异。以后不再赘述。如有问题,再支出。 |
iconst_iconst 的完整写法是 iconst_ , 包含 iconst_m1 、 iconst_0 、 iconst_1 、 iconst_2 、 iconst_3 、 iconst_4 和 iconst_5 五个操作码。
/ * 字节码示例代码 * * @author D瓜哥 · https://www.diguage.com */ publ