Java 的一些指令解析
在java文件编译后,我们可以使用 javap -c xxx [其中xxx为编译后的class文件名,不包含后缀] 后可以得到编译器生成的字节码。
下面我们来看一个例子:
public class TestJava {
public static void main(String[] args) {
int array[] = {-1,2,3,4};
for(int len=array.length,i=0;i<len;i++){
System.out.println(array[i]);
}
}
}
1.执行javap -c TestJava 我们可以得到以下信息:
public class utils.jjtest.TestJava {
public utils.jjtest.TestJava();
Code:
0: aload_0 //从局部变量0中装载引用类型值入栈。
1: invokespecial #8 // Method java/lang/Object."<init>":()V 调用构造方法、父类方法
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_4 //常量4(int)入栈
1: newarray int //创建整型,长度为4的的数组
3: dup //复制栈顶一个字长的数据,将复制后的数据压栈。
4: iconst_0 //常量0(int)入栈
5: iconst_m1 //常量-1(int)入栈
6: iastore //将-1保存在数组位置0中即array[0]=1
7: dup
8: iconst_1
9: iconst_2
10: iastore
11: dup
12: iconst_2
13: iconst_3
14: iastore
15: dup
16: iconst_3
17: iconst_4
18: iastore
19: astore_1 //局部变量1指向数组 即int array[] = {-1,2,3,4};
20: aload_1 //从局部变量1中装载引用类型值入栈。
21: arraylength //获得一维数组的长度
22: istore_2 //保存在局部变量2(int)中 即 int len=4;
23: iconst_0 //常量0(int)入栈
24: istore_3 //保存局部变量3(int)中 即 int i=0;
25: goto 40 // 跳转到40 【--0】
28: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;【--4】
31: aload_1 // 从局部变量1中装载引用类型值入栈。【--5】
32: iload_3 // 读取局部变量3的值【--6】
33: iaload // 读取整形数组 【--7】
34: invokevirtual #22 // Method java/io/PrintStream.println:(I)V //打印【--8】
37: iinc 3, 1 //局部变量3 自增 1 【--9】 即i++
40: iload_3 //读取局部变量3的值【--1】
41: iload_2 //读取局部变量2的值【--2】
42: if_icmplt 28 //如果局部变量3小于局部变量2 则跳到28 【跳转--3】 即 i<len
45: return
}
2.相关的解析已经在字节码中注释,如果有不对的地方请指出。
参考资料
1.http://www.iteye.com/topic/779102
2.http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html