对栈帧中操作数栈和局部变量表的理解

栈帧包含局部变量表和操作数栈

操作数栈的单个元素(格子)长度是 4 个字节,所以byte、char、short长度会补齐 4 个字节,long会占两个元素

题目1

public class Demo {
    public static void main(String[] args) {
        int a = 10;
        int b = a++ + ++a + a--;
        System.out.println(a);// 11
        System.out.println(b);// 34
    }

部分字节码

public static void main(java.lang.String[]);
	descriptor: ([Ljava/lang/String;)V
	flags: (0x0009) ACC_PUBLIC, ACC_STATIC
	Code:
		stack=2, locals=3, args_size=1
            0: bipush 			10		//把 10 放入操作数栈
            2: istore_1					//将操作数栈弹出放进局部变量表一号位置,此时 a = 10
            3: iload_1					//将局部变量表中一号位置的值压入操作数栈中
            4: iinc 			1, 1	        //两个参数,分别表示对哪个槽位自增,自增步长
            7: iinc 			1, 1
            10: iload_1
            11: iadd
            12: iload_1
            13: iinc 			1, -1
            16: iadd
            17: istore_2
            21: iload_1
            22: invokevirtual 	#3 // Method 	java/io/PrintStream.println:(I)V
	    25: getstatic 	#2 // Field 	java/lang/System.out:Ljava/io/PrintStream;
            28: iload_2
            29: invokevirtual 	#3 // Method 	java/io/PrintStream.println:(I)V
	    32: return
	LineNumberTable:
            line 8: 0
            line 9: 3
            line 10: 18
            line 11: 25
            line 12: 32
        LocalVariableTable:
	      Start Length Slot Name Signature
                0     33    0   args [Ljava/lang/String;
                3     30    1    a         I
               18     15    2    b         I 

前提:

  • 注意 iinc(自增) 指令是直接在局部变量 slot 上进行运算。
  • a++++a 的区别是先执行 iload(读取a) 还是 先执行 iinc。a++是先iload再iinc,++a相反。

题目2

public class Demo {
    public static void main(String[] args) {
        int i = 1;
        i = i++;
        int j = i++;
        int k = i + ++i * i++;
        System.out.println(i);
        System.out.println(j);
        System.out.println(k);
    }

答案:i:4,j:1,k:11(2+3*3) 用局部变量表和操作数栈来分析。

posted @ 2023-05-27 16:25  小陈code  阅读(47)  评论(0)    收藏  举报