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

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()解释

在这里插入图片描述
由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个this了,然后来看字节码,bipush 10表示需要往操作数栈中添加数值10,istore_1表示数值10需要从操作数栈中弹出来,然后添加到局部变量表中下标为1的位置,iinc是自增操作,后面第一个1代表对局部变量表中下标为1上的数值进行自增,也就是那个10,by 1表示自增1就可以了,那局部变量表中下标为1的数值就变成了11

3、method2()解释

在这里插入图片描述
可以看出,字节码和上面的一样,说明单独使用++ii++是没有区别的,还记得for(int i = 0; i < 10; i++){***}这种操作吗,其实把里面的i++换成++i也是没有问题的

4、method3()解释

在这里插入图片描述

由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为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位置上的值就变成了11iload_3代表将局部变量表中下标为3的数值11取出来压入操作数栈中,istore_4代表将数值11弹出栈,然后放入到局部变量表中下标为4的位置,这也就是变量b所在的位置

5、method4()解释

在这里插入图片描述
虽然字节码不多,但是这个是最有意思的,由于该方法不是静态方法,所以在方法被调用之前局部变量表中下标为0的位置已经有一个this了,然后来看字节码,bipush 10表示需要往操作数栈中添加数值10,istore_1表示数值10需要从操作数栈中弹出来,然后添加到局部变量表中下标为1的位置,iload_1表示将局部变量表中下标为1上的值取出来压入操作数栈中,该值正是10iinc 1 by 1的含义在method1()解释中已经说过了,执行之后的结果是局部变量表中下标为1的位置上的i变成了11,这里不再赘述,istore_1表示将操作数栈中的数值10弹出栈,然后放入局部变量表中下标为1的位置,这也就是变量i所在的位置,所以最终i变成了10,确实很有意思,很神奇

6、总结

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

i++: ++放在后面,那就先赋值,再++

++i: ++放在前面,那就先++,再赋值

不过需要小心method4()方法中的i = i++这种的

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页