Android Gradle学习(十)- java字节码指令集解读

一、加载与存储指令

1.1、加载常量到操作数栈

类别 指令 作用 常量范围 / 说明 Java 代码示例 字节码示例
int 常量 iconst_m1 加载 int 常量 -1 -1 int a = -1; iconst_m1 istore_1
iconst_0 加载 int 常量 0 0 int b = 0; iconst_0 istore_2
iconst_5 加载 int 常量 5 5 int c = 5; iconst_5 istore_3
bipush 加载 8 位有符号 int 常量 -128~127 int d = 100; bipush 100 istore_4
sipush 加载 16 位有符号 int 常量 -32768~32767 int e = 2000; sipush 2000 istore_5
ldc 从常量池加载 int 超出sipush范围的 int int f = 40000; ldc #2 istore_6
long 常量 lconst_0 加载 long 常量 0L 0L long g = 0L; lconst_0 lstore_7
lconst_1 加载 long 常量 1L 1L long h = 1L; lconst_1 lstore_9
ldc2_w 从常量池加载 long 超出lconst范围的 long long i = 1000L; ldc2_w #3 lstore_11
float 常量 fconst_0 加载 float 常量 0.0f 0.0f float j = 0.0f; fconst_0 fstore_13
fconst_2 加载 float 常量 2.0f 2.0f float k = 2.0f; fconst_2 fstore_14
ldc 从常量池加载 float 超出fconst范围的 float float l = 3.14f; ldc #4 fstore_15
double 常量 dconst_0 加载 double 常量 0.0 0.0 double m = 0.0; dconst_0 dstore_16
dconst_1 加载 double 常量 1.0 1.0 double n = 1.0; dconst_1 dstore_18
ldc2_w 从常量池加载 double 超出dconst范围的 double double o = 3.1415; ldc2_w #5 dstore_20
字符串常量 ldc 从常量池加载字符串 所有字符串常量 String p = "hello"; ldc #6 astore_22

1.2、从局部变量表加载到操作数栈

数据类型 简化指令(索引 0~3) 通用指令(任意索引) 作用 Java 代码示例 字节码示例
int iload_1 iload <n> 加载 int 变量 int q = d;(d 在索引 4) iload_4 istore_23
long lload_1 lload <n> 加载 long 变量 long r = i;(i 在索引 11) lload 11 lstore_24
float fload_2 fload <n> 加载 float 变量 float s = l;(l 在索引 15) fload_15 fstore_26
double dload_3 dload <n> 加载 double 变量 double t = o;(o 在索引 20) dload 20 dstore_27
引用类型 aload_0 aload <n> 加载对象引用(如this Object u = this; aload_0 astore_29
引用类型 aload_1 aload <n> 加载对象引用 String v = p;(p 在索引 22) aload_22 astore_30

1.3、从操作数栈存储到局部变量表

数据类型 简化指令(索引 0~3) 通用指令(任意索引) 作用 Java 代码示例 字节码示例
int istore_1 istore <n> 存储 int 值 int w = 10; bipush 10 istore_31
long lstore_2 lstore <n> 存储 long 值 long x = 100000L; ldc2_w #7 lstore 32
float fstore_3 fstore <n> 存储 float 值 float y = 5.5f; ldc #8 fstore_34
double dstore_0 dstore <n> 存储 double 值 double z = 9.9; ldc2_w #9 dstore_35
引用类型 astore_1 astore <n> 存储对象引用 Object obj = new Object(); new #10 dup invokespecial #11 astore_37

1.4、宽索引指令

指令 作用 说明 Java 代码示例 字节码示例
wide 扩展局部变量表索引范围 支持索引≥256 的变量 int arr[] = new int[300]; int val = arr[256];(假设 val 在索引 256) wide iload 256 istore 38

二、运算指令

2.1、算术运算指令(对操作数栈中的数值执行算术操作)

数据类型 指令 作用 说明 Java 代码示例 字节码示例
int iadd 加法 栈顶两 int 相加,结果入栈 int a = 2 + 3; iconst_2 iconst_3 iadd istore_1
isub 减法 栈顶两 int 相减,结果入栈 int b = 5 - 1; iconst_5 iconst_1 isub istore_2
imul 乘法 栈顶两 int 相乘,结果入栈 int c = 3 * 4; iconst_3 iconst_4 imul istore_3
idiv 除法 栈顶两 int 相除,结果入栈 int d = 10 / 2; bipush 10 iconst_2 idiv istore_4
irem 取余 栈顶两 int 取余,结果入栈 int e = 7 % 3; bipush 7 iconst_3 irem istore_5
ineg 取反 栈顶 int 取相反数,结果入栈 int f = -a; iload_1 ineg istore_6
long ladd 加法 栈顶两 long 相加,结果入栈 long g = 100L + 200L; ldc2_w #2 ldc2_w #3 ladd lstore_7
lsub 减法 栈顶两 long 相减,结果入栈 long h = 500L - 150L; ldc2_w #4 ldc2_w #5 lsub lstore_9
lmul 乘法 栈顶两 long 相乘,结果入栈 long i = 10L * 30L; lconst_10 ldc2_w #6 lmul lstore_11
float fadd 加法 栈顶两 float 相加,结果入栈 float j = 2.5f + 1.5f; ldc #7 ldc #8 fadd fstore_13
fsub 减法 栈顶两 float 相减,结果入栈 float k = 5.0f - 2.3f; fconst_5 ldc #9 fsub fstore_14
double dadd 加法 栈顶两 double 相加,结果入栈 double l = 3.14 + 2.71; ldc2_w #10 ldc2_w #11 dadd dstore_15
ddiv 除法 栈顶两 double 相除,结果入栈 double m = 10.0 / 3.0; ldc2_w #12 ldc2_w #13 ddiv dstore_17

2.2、位运算指令(对操作数栈中的整数执行位操作)

数据类型 指令 作用 说明 Java 代码示例 字节码示例
int ishl 左移 栈顶两 int,低位移高,结果入栈 int n = 8 << 2; bipush 8 iconst_2 ishl istore_19
ishr 算术右移 带符号右移,高位补符号位 int o = -8 >> 2; bipush -8 iconst_2 ishr istore_20
iushr 逻辑右移 无符号右移,高位补 0 int p = 8 >>> 2; bipush 8 iconst_2 iushr istore_21
iand 按位与 栈顶两 int 按位与,结果入栈 int q = 3 & 5; iconst_3 iconst_5 iand istore_22
ior 按位或 栈顶两 int 按位或,结果入栈 `int r = 3 5;` iconst_3 iconst_5 ior istore_23
ixor 按位异或 栈顶两 int 按位异或,结果入栈 int s = 3 ^ 5; iconst_3 iconst_5 ixor istore_24
long lshl 左移 栈顶两 long 左移,结果入栈 long t = 4L << 3; lconst_4 iconst_3 lshl lstore_25
land 按位与 栈顶两 long 按位与,结果入栈 long u = 0x0FL & 0xF0L; ldc2_w #14 ldc2_w #15 land lstore_27

2.3、比较运算指令(比较操作数栈中的值,结果用于控制流转)

数据类型 指令 作用 说明 Java 代码示例 字节码示例
int if_icmpeq 相等则跳转 比较两 int,相等则跳转到指定偏移量 if(a == b) { ... } iload_1 iload_2 if_icmpeq 30
if_icmpne 不等则跳转 比较两 int,不等则跳转 if(a != b) { ... } iload_1 iload_2 if_icmpne 40
if_icmplt 小于则跳转 比较两 int,前者小于后者则跳转 if(a < b) { ... } iload_1 iload_2 if_icmplt 50
if_icmpgt 大于则跳转 比较两 int,前者大于后者则跳转 if(a > b) { ... } iload_1 iload_2 if_icmpgt 60
long lcmpeq 相等则跳转 比较两 long,相等则跳转 if(g == h) { ... } lload_7 lload_9 lcmpeq 70
float fcmpl 比较后压栈 比较两 float,结果(-1/0/1)入栈(NaN 视为小于) if(j < k) { ... } fload_13 fload_14 fcmpl iflt 80
fcmpg 比较后压栈 比较两 float,结果(-1/0/1)入栈(NaN 视为大于) if(j > k) { ... } fload_13 fload_14 fcmpg ifgt 90
引用类型 if_acmpeq 引用相等则跳转 比较两对象引用,地址相同则跳转 if(obj1 == obj2) { ... } aload_28 aload_29 if_acmpeq 100
if_acmpne 引用不等则跳转 比较两对象引用,地址不同则跳转 if(obj1 != obj2) { ... } aload_28 aload_29 if_acmpne 110

三、对象操作指令

3.1、对象创建与初始化指令

指令 作用 说明 Java 代码示例 字节码示例
new 创建类实例 在堆中分配对象实例空间,返回对象引用(未初始化) Person p = new Person(); new #2 <Person> dup invokespecial #3 <Person.<init>> astore_1
invokespecial 调用构造方法 用于初始化对象(调用<init>方法) 隐含在new表达式中 同上(invokespecial为构造方法调用)

3.2、字段访问指令

指令 作用 说明 Java 代码示例 字节码示例
getfield 获取对象实例字段值 从对象中读取实例变量的值 String name = p.name; aload_1 getfield #4 <Person.name> astore_2
putfield 设置对象实例字段值 向对象的实例变量写入值 p.age = 20; aload_1 bipush 20 putfield #5 <Person.age>
getstatic 获取类静态字段值 读取类的静态变量(类级变量) int count = Person.total; getstatic #6 <Person.total> istore_3
putstatic 设置类静态字段值 写入类的静态变量 Person.total = 100; bipush 100 putstatic #6 <Person.total>

3.3、数组操作指令

指令 作用 说明 Java 代码示例 字节码示例
newarray 创建基本类型数组 用于创建 int、float 等基本类型数组 int[] arr = new int[5]; iconst_5 newarray int astore_4
anewarray 创建引用类型数组 用于创建对象数组(如 String []) String[] strs = new String[3]; iconst_3 anewarray #7 <java/lang/String> astore_5
multianewarray 创建多维数组 用于创建二维及以上数组 int[][] matrix = new int[2][3]; iconst_2 iconst_3 multianewarray #8 <[[I> 2 astore_6
arraylength 获取数组长度 将数组长度压入操作数栈 int len = arr.length; aload_4 arraylength istore_7
iaload 读取 int 数组元素 从 int 数组指定索引读取值 int val = arr[0]; aload_4 iconst_0 iaload istore_8
iastore 写入 int 数组元素 向 int 数组指定索引写入值 arr[1] = 100; aload_4 iconst_1 bipush 100 iastore
aaload 读取引用数组元素 从对象数组指定索引读取引用 String s = strs[0]; aload_5 iconst_0 aaload astore_9
aastore 写入引用数组元素 向对象数组指定索引写入引用 strs[1] = "hello"; aload_5 iconst_1 ldc #9 <hello> aastore

3.4、类型检查指令

指令 作用 说明 Java 代码示例 字节码示例
instanceof 检查对象类型 判断对象是否为指定类的实例,结果(1/0)入栈 boolean isPerson = obj instanceof Person; aload_10 instanceof #2 <Person> istore_11
checkcast 类型转换检查 确保对象可转换为目标类型,失败抛 ClassCastException Person p2 = (Person) obj; aload_10 checkcast #2 <Person> astore_12

四、方法调用与返回指令

4.1、方法调用指令

指令 作用 说明 Java 代码示例 字节码示例
invokestatic 调用静态方法 调用类的静态方法(无实例参与),属于静态绑定 Math.max(3, 5); iconst_3 iconst_5 invokestatic #2 <java/lang/Math.max>
invokespecial 调用特殊方法 用于调用构造方法(<init>)、私有方法、父类方法,属于静态绑定 super();(构造方法中) aload_0 invokespecial #3 <java/lang/Object.<init>>
this.privateMethod(); aload_0 invokespecial #4 <Person.privateMethod>
invokevirtual 调用实例方法 调用对象的实例方法(非私有、非构造方法),支持动态绑定(多态) p.getName(); aload_1 invokevirtual #5 <Person.getName>
invokeinterface 调用接口方法 调用接口中定义的方法,动态绑定到实现类 list.add("item"); aload_2 ldc #6 <item> invokeinterface #7 <java/util/List.add> 2
invokedynamic 调用动态方法 支持动态语言特性(如 Lambda 表达式),绑定逻辑由引导方法决定 Runnable r = () -> {}; invokedynamic #8 <run, BootstrapMethod #0>

4.2、方法返回指令

指令 作用 说明 Java 代码示例 字节码示例
return 无返回值返回 用于void方法,无值返回 void greet() { return; } return
ireturn 返回 int 类型 从方法返回 int 值(包括 boolean、byte、char、short 的包装返回) int getAge() { return 20; } bipush 20 ireturn
lreturn 返回 long 类型 从方法返回 long 值 long getTimestamp() { return 123456L; } ldc2_w #9 lreturn
freturn 返回 float 类型 从方法返回 float 值 float getScore() { return 95.5f; } ldc #10 freturn
dreturn 返回 double 类型 从方法返回 double 值 double getPrice() { return 19.99; } ldc2_w #11 dreturn
areturn 返回引用类型 从方法返回对象或数组引用 String getName() { return name; } aload_0 getfield #12 <Person.name> areturn

五、控制转移指令

5.1、条件分支指令(基于比较结果跳转)

指令 作用 说明 Java 代码示例 字节码示例
int 值比较 if_icmpeq 两 int 相等则跳转 if(a == b) { ... } iload_1 iload_2 if_icmpeq 20
if_icmpne 两 int 不等则跳转 if(a != b) { ... } iload_1 iload_2 if_icmpne 30
if_icmplt 前 int < 后 int 则跳转 if(a < b) { ... } iload_1 iload_2 if_icmplt 40
if_icmpgt 前 int > 后 int 则跳转 if(a > b) { ... } iload_1 iload_2 if_icmpgt 50
if_icmple 前 int <= 后 int 则跳转 if(a <= b) { ... } iload_1 iload_2 if_icmple 60
if_icmpge 前 int >= 后 int 则跳转 if(a >= b) { ... } iload_1 iload_2 if_icmpge 70
引用比较 if_acmpeq 两引用相等则跳转 if(obj1 == obj2) { ... } aload_3 aload_4 if_acmpeq 80
if_acmpne 两引用不等则跳转 if(obj1 != obj2) { ... } aload_3 aload_4 if_acmpne 90
栈顶值判断 ifeq 栈顶 int 为 0 则跳转 if(flag == 0) { ... } iload_5 ifeq 100
ifne 栈顶 int 不为 0 则跳转 if(flag != 0) { ... } iload_5 ifne 110
iflt 栈顶 int < 0 则跳转 if(count < 0) { ... } iload_6 iflt 120
ifgt 栈顶 int > 0 则跳转 if(count > 0) { ... } iload_6 ifgt 130
null 判断 ifnull 引用为 null 则跳转 if(obj == null) { ... } aload_3 ifnull 140
ifnonnull 引用非 null 则跳转 if(obj != null) { ... } aload_3 ifnonnull 150

5.2、无条件分支指令(直接跳转)

指令 作用 说明 Java 代码示例 字节码示例
goto 无条件跳转到指定偏移量 短偏移量跳转(16 位偏移) loop: { ...; goto loop; } goto 5(跳转到偏移量 5)
goto_w 无条件跳转到宽偏移量 长偏移量跳转(32 位偏移,支持更大范围) 大型循环或跳转距离远时 goto_w 1000(跳转到偏移量 1000)

5.3、多分支跳转指令(switch 语句专用)

指令 作用 说明 Java 代码示例 字节码示例
tableswitch 连续 case 值的多分支跳转 适用于 case 值连续的 switch,通过索引表快速定位 switch(a) { case 1: ...; case 2: ...; } tableswitch 1: 20 2: 30 default: 40
lookupswitch 离散 case 值的多分支跳转 适用于 case 值不连续的 switch,通过查找表匹配 switch(b) { case 10: ...; case 200: ...; } lookupswitch 10: 50 200: 60 default: 70

5.4、异常处理指令

指令 作用 说明 Java 代码示例 字节码示例
athrow 抛出异常 将操作数栈顶的异常对象抛出 throw new Exception(); new #8 <java/lang/Exception> dup invokespecial #9 <Exception.<init>> athrow

六、栈操作与同步指令

6.1、栈操作指令(直接操作操作数栈)

指令 作用 说明 Java 代码示例 字节码示例
pop 弹出栈顶 1 个元素 用于清理操作数栈中不再使用的单元素(如 int、float、引用) 临时变量运算后清理 iconst_1 iconst_2 iadd pop(丢弃结果)
pop2 弹出栈顶 2 个元素 用于清理占 2 个 Slot 的元素(long、double)或连续 2 个单元素 清理 long 类型临时值 lconst_1 pop2(丢弃 long 值)
dup 复制栈顶 1 个元素并压入栈 复制单元素(如 int、引用),栈深度 + 1 对象创建时复制引用 new #2 <Person> dup(复制对象引用)invokespecial #3 <Person.<init>>
dup_x1 复制栈顶元素并插入到下方第 2 个元素前 调整栈结构,复制后顺序:[原栈顶 - 1, 复制值,原栈顶] 复杂运算时调整操作数顺序 iconst_1 iconst_2 dup_x1(栈变为 [1,2,1])
dup_x2 复制栈顶元素并插入到下方第 3 个元素前 支持下方是单元素或 long/double(占 2 个 Slot) 多操作数调整 iconst_1 iconst_2 iconst_3 dup_x2(栈变为 [1,3,2,3])
dup2 复制栈顶 2 个元素并压入栈 复制 long/double 或两个单元素,栈深度 + 2 复制 long 类型值 lconst_1 dup2(栈变为 [1L,1L])
dup2_x1 复制栈顶 2 个元素并插入到下方第 3 个元素前 调整包含 long/double 的栈结构 复杂 long 运算调整 lconst_1 iconst_2 dup2_x1(栈变为 [1L,2,1L])
dup2_x2 复制栈顶 2 个元素并插入到下方第 4 个元素前 最灵活的双元素复制指令 多类型混合调整 iconst_1 lconst_2 dup2_x2(栈变为 [1,2L,1,2L])
swap 交换栈顶两个单元素 仅用于两个单元素(如 int、引用),不支持 long/double 交换操作数顺序 iconst_1 iconst_2 swap(栈变为 [2,1])

6.2、同步指令(实现 synchronized 同步)

指令 作用 说明 Java 代码示例 字节码示例
monitorenter 获取对象监视器锁 进入同步块时获取锁,同一时间仅一个线程可获取 synchronized(obj) { ... } aload_1 monitorenter
monitorexit 释放对象监视器锁 退出同步块时释放锁,确保锁最终会被释放(包括异常路径) 同步块结束处 monitorexit
相关推荐
华农第一蒟蒻2 小时前
谈谈跨域问题
java·后端·nginx·安全·okhttp·c5全栈
菜鸟plus+2 小时前
MinIO
java
艾菜籽2 小时前
JVM中的垃圾回收机制
java·jvm
敲代码的嘎仔3 小时前
JavaWeb零基础学习Day1——HTML&CSS
java·开发语言·前端·css·学习·html·学习方法
Terio_my8 小时前
Java bean 数据校验
java·开发语言·python
超级大只老咪9 小时前
何为“类”?(Java基础语法)
java·开发语言·前端
我笑了OvO9 小时前
C++类和对象(1)
java·开发语言·c++·类和对象
weixin_4365250711 小时前
Gitee - IDEA 主支 master 和分支 dev 的使用
java·ide·intellij-idea
sheji341611 小时前
【开题答辩全过程】以 YF精品视频动漫平台为例,包含答辩的问题和答案
java·eclipse