考虑如下一个静态的方法:
Java代码
publicstaticvoidtest() {
inta =1;
intb =2;
intc = a + b;
intd = a * c;
}
public static void test() {
int a = 1;
int b = 2;
int c = a + b;
int d = a * c;
}
当我们对其进行编译,发现该方法的字节码为:
Java代码
publicstaticvoidtest();
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=0
0: iconst_1
1: istore_0
2: iconst_2
3: istore_1
4: iload_0
5: iload_1
6: iadd
7: istore_2
8: iload_0
9: iload_2
10: imul
11: istore_3
12:return
LineNumberTable:
line9:0
line10:2
line11:4
line12:8
line13:12
public static void test();
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=0
0: iconst_1
1: istore_0
2: iconst_2
3: istore_1
4: iload_0
5: iload_1
6: iadd
7: istore_2
8: iload_0
9: iload_2
10: imul
11: istore_3
12: return
LineNumberTable:
line 9: 0
line 10: 2
line 11: 4
line 12: 8
line 13: 12
flags属性指明方法的修饰符,这里是public 和 static。
Code属性中JVM栈大小为2,局部变量区大小为4(因为只有4个局部变量,并且没有参数和hidden_this)。
下面解析每一条指令:
iconst_1 将int类型值1压入JVM栈。
istore_0 弹出栈,并将弹出值赋值给第一个变量a(局部变量区是一个数组,以0开始为索引),
同理 iconst_2 和 istore_1 将int类型值2压入栈,弹出栈并赋值给第二个变量b。
iload_0 将局部变量区的第1个变量压入栈(注意该变量依然存储在局部变量区中).
iload_1 将局部变量区的第2个变量压入栈。
iadd 两次弹出栈,并对它们执行加法运算(add),然后将结果压栈。
istore_2 弹出栈,并将出栈值赋值给第三个变量c。(此时栈为空).
最后几条指令可以自己去推敲(imul指令即int类型的乘法运算)。
return指令 表名该方法的正常返回(返回为void)。
每条字节码指令前面的数字的单位为字节。每个操作码占1个字节(所以JVM虚拟机最多容纳256条指令),操作码后可有0或多条操作数。