天天看点

从字节码的角度分析 i++ 和 ++i

目录

      • 1、代码
      • 2、method1()解释
      • 3、method2()解释
      • 4、method3()解释
      • 5、method4()解释
      • 6、总结

1、代码

public class Test {
    public void method1() {
        int i = 10;
        i++;
    }
    public void method2() {
        int i = 10;
        ++i;
    }
    public void method3() {
        int i = 10;
        int a = i++;
        int j = 10;
        int b = ++j;
    }
    public void method4() {
        int i = 10;
        i = i++;
    }
}
           

2、method1()解释

从字节码的角度分析 i++ 和 ++i

由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个

this

了,然后来看字节码,

bipush 10

表示需要往操作数栈中添加数值10,

istore_1

表示数值10需要从操作数栈中弹出来,然后添加到局部变量表中下标为1的位置,

iinc

是自增操作,后面第一个

1

代表对局部变量表中下标为1上的数值进行自增,也就是那个10,

by 1

表示自增

1

就可以了,那局部变量表中下标为

1

的数值就变成了

11

3、method2()解释

从字节码的角度分析 i++ 和 ++i

可以看出,字节码和上面的一样,说明单独使用

++i

i++

是没有区别的,还记得

for(int i = 0; i < 10; i++){***}

这种操作吗,其实把里面的

i++

换成

++i

也是没有问题的

4、method3()解释

从字节码的角度分析 i++ 和 ++i

由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个

this

了,然后来看字节码,

bipush 10

表示需要往操作数栈中添加数值10,

istore_1

表示数值

10

需要从操作数栈中弹出来,然后添加到局部变量表中下标为

1

的位置,

iload_1

表示将局部变量表中下标为1上的值取出来压入操作数栈中,该值正是10,

iinc 1 by 1

的含义在

method1()解释

中已经说过了,执行之后的结果是局部变量表中下标为

1

的位置上的

i

变成了

11

,这里不再赘述,

istore_2

表示将操作数栈中的数值

10

弹出栈,然后放入局部变量表中下标为

2

的位置,这也就是变量

a

所在的位置

之后是

bipush 10

代表将数值

10

压入操作数栈,

istore_3

代表将

10

弹出操作数栈,然后放入局部变量表中下标为

3

的位置,

iinc 3 by 1

代表将局部变量表中下标为

3

位置上的数,

10

自增

1

,那么该局部变量表中下标为

3

位置上的值就变成了

11

iload_3

代表将局部变量表中下标为

3

的数值

11

取出来压入操作数栈中,

istore_4

代表将数值

11

弹出栈,然后放入到局部变量表中下标为

4

的位置,这也就是变量

b

所在的位置

5、method4()解释

从字节码的角度分析 i++ 和 ++i

虽然字节码不多,但是这个是最有意思的,由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个

this

了,然后来看字节码,

bipush 10

表示需要往操作数栈中添加数值10,

istore_1

表示数值

10

需要从操作数栈中弹出来,然后添加到局部变量表中下标为

1

的位置,

iload_1

表示将局部变量表中下标为1上的值取出来压入操作数栈中,该值正是

10

iinc 1 by 1

的含义在

method1()解释

中已经说过了,执行之后的结果是局部变量表中下标为

1

的位置上的

i

变成了

11

,这里不再赘述,

istore_1

表示将操作数栈中的数值

10

弹出栈,然后放入局部变量表中下标为

1

的位置,这也就是变量

i

所在的位置,所以最终

i

变成了

10

,确实很有意思,很神奇

6、总结

一般遇到这种问题,可以简单来思考就行了

i++:

++放在后面

,那就

先赋值,再++

++i:

++放在前面

,那就

先++,再赋值

不过需要小心

method4()

方法中的

i = i++

这种的

继续阅读