案例代码如下:
1 public class JVMTest { 2 public static Integer num = 10; 3 4 public int add(int i){ 5 int j = 5; 6 int k = i+j; 7 j++; 8 k = num + j; 9 return k; 10 } 11 12 public static void main(String[] args){ 13 System.out.println(new JVMTest().add(4)); 14 } 15 }
编译之后主要指令集如下:
1 { 2 public static java.lang.Integer num; 3 descriptor: Ljava/lang/Integer; 4 flags: ACC_PUBLIC, ACC_STATIC 5 6 public com.lucky.grpc.JVMTest(); 7 descriptor: ()V 8 flags: ACC_PUBLIC 9 Code: 10 stack=1, locals=1, args_size=1 11 0: aload_0 12 1: invokespecial #1 // Method java/lang/Object."<init>":()V 13 4: return 14 LineNumberTable: 15 line 3: 0 16 17 public int add(int); 18 descriptor: (I)I 19 flags: ACC_PUBLIC 20 Code: 21 stack=2, locals=4, args_size=2 22 0: iconst_5 23 1: istore_2 24 2: iload_1 25 3: iload_2 26 4: iadd 27 5: istore_3 28 6: iinc 2, 1 29 9: getstatic #2 // Field num:Ljava/lang/Integer; 30 12: invokevirtual #3 // Method java/lang/Integer.intValue:()I 31 15: iload_2 32 16: iadd 33 17: istore_3 34 18: iload_3 35 19: ireturn 36 LineNumberTable: 37 line 7: 0 38 line 8: 2 39 line 9: 6 40 line 10: 9 41 line 11: 18 42 43 public static void main(java.lang.String[]); 44 descriptor: ([Ljava/lang/String;)V 45 flags: ACC_PUBLIC, ACC_STATIC 46 Code: 47 stack=3, locals=1, args_size=1 48 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 49 3: new #5 // class com/lucky/grpc/JVMTest 50 6: dup 51 7: invokespecial #6 // Method "<init>":()V 52 10: iconst_4 53 11: invokevirtual #7 // Method add:(I)I 54 14: invokevirtual #8 // Method java/io/PrintStream.println:(I)V 55 17: return 56 LineNumberTable: 57 line 15: 0 58 line 16: 17 59 60 static {}; 61 descriptor: ()V 62 flags: ACC_STATIC 63 Code: 64 stack=1, locals=0, args_size=0 65 0: bipush 10 66 2: invokestatic #9 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 67 5: putstatic #2 // Field num:Ljava/lang/Integer; 68 8: return 69 LineNumberTable: 70 line 4: 0 71 }
其中第17行到第41行是add方法的指令,接下来就一行一行图解虚拟机栈是如何执行的!
第一步:iconst_5 :将int类型的常量5压入操作数栈
第二步:istore_2 :将操作数栈顶中int类型数据放入局部常量表下标为2的位置,从0开始数也就是第三个位置
第三步:iload_1 :
是