从字节码角度深入剖析:i++和++i的逻辑

发布时间 2023-11-07 11:52:16作者: 伊万夫斯基

i++和++i的深入剖析

先说结论:

  • i++或++i不参与运算的话,i++和++i的指令代码是没有区别的。
  • i++或++i参与运算。从字节码指令角度来看,主要是看先load还是先执行iinc 1 by 1的顺序。

不参与运算

先把0加载到操作数栈上,弹出放到slot1的局部变量表位置,iinc 1 by 1把索引为1的值拿到执行加1操作放到slot1位置。

 0 iconst_0
 1 istore_1
 2 iinc 1 by 1

参与运算

i++参与运算。从字节码指令角度来看,主要是看先load还是先执行iinc 1 by 1的顺序。

i++: 先把slot1位置的值加载到操作数栈,之后把对应slot1位置的元素自增,现在栈顶放的是原来的i值,所以再从操作数栈拿到栈顶值之后放到slot2位置;

++i:先执行slot1位置自增逻辑,之后把自增后的值load到操作数,此时操作数栈是自增后的值,再通过store放到局部变量表slot2位置,得到的是自增后的值。

    @Test
    public void testI2() {
        int a = 5;
        int c = a++;
        System.out.println(c);
//        0 iconst_5 // 把5放到操作数栈
//        1 istore_1 // 5出栈,放入局部变量表slot1位置;
//        2 iload_1 // 把slot1的5加载到操作数栈中;
//        3 iinc 1 by 1 // 把slot1位置的5执行加一操作得到6
//        6 istore_2 // 5出栈,放到局部变量表slot2位置;
//        7 return
    }
    @Test
    public void testI3() {
        int a = 5;
        int c = ++a;
        System.out.println(c);

//        0 iconst_5 // 把5放到操作数栈
//        1 istore_1 // 5出栈,放入局部变量表slot1位置;
//        2 iinc 1 by 1 // 把slot1位置的5执行加一操作得到6
//        5 iload_1 // 把slot1位置的6放到操作数栈;
//        6 istore_2 // 6出栈,存到slot2位置;
//        7 return

    }