在 Java 虚拟机指令(操作码)集 中给出了一个操作码的列表。针对所有的指令,仅仅给出了一个大概介绍,对理解来说可以说毫无助力。为了弥补这个短板,这里也学习 “Hessian 协议解释与实战”系列 那样,来一个详细解释和实战,配合实例来做个深入分析和讲解。这是这个系列的第一篇文章,就以列表中第一部分“常量”指令开始。
从 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."<init>":()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_<i>
iconst
的完整写法是 iconst_<i>
, 包含 iconst_m1 、 iconst_0 、 iconst_1 、 iconst_2 、 iconst_3 、 iconst_4 和 iconst_5 五个操作码。
/ * 字节码示例代码 * * @author D瓜哥 ·