a++,++a再解析

文章目录


问题

我们都知道:

  • ++a,是先增后用
  • a++,是先用后增

那么做一些下面这道题。

    public static void main(String argc[]){
        int a=0;
        a=a++;
        System.out.println(a);
    }

由于a++是先用后增,于是a的值0先用,赋给a为0,然后a后增,此时a的值为1。所以结果就为1了。

相信很多人都会得出1这个结果,可结果是:0

在开始解析之前,我们先说一下为什么。

  • ++a,先增后用,增是直接操作占局部变量表的,后用是将变量a的值放入操作数栈中。对应与iinc指令。
  • a++,先用后增。先用是把a的值放到操作数栈中,后增是将局部变量表中a的值加一。

解析

a++

    public static void main(String argc[]){
        int a=0;
        a=a++;
        System.out.println(a);
    }

使用javap -verbose反汇编的结果。

 		 0: iconst_0
         1: istore_1
         2: iload_1 // 先用
         3: iinc          1, 1 // 后加
         6: istore_1 //赋值算符=
         7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        10: iload_1
        11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        14: return

每一个函数的调用都伴随这一个栈帧的入栈与出栈。栈帧中有操作数栈、局部变量表等结构。栈帧结构可以参考虚拟机字节码执行引擎——运行时栈帧结构

  • iconst_0。将一个常量0添加到操作数栈中。
    在这里插入图片描述
图1 iconst_0
  • istore_1。将一个操作数栈顶数0拿出来放到局部变量表第1个slot槽中。
    在这里插入图片描述
图2 istore_1
  • iload_1。将局部变量表中槽1的局部变量的值0放到操作数栈中。
    在这里插入图片描述
图3 iload_1
  • iinc 1, 1。将局部变量表中槽1的值加1,变量a的值为1。对应的是a++指令。
    在这里插入图片描述
图4 iinc 1, 1
  • istore_1。将操作数栈顶元素0拿出来放到局部变量表中槽1位置,意思是a的值1被覆盖了。其实这条指令对应与a=a++中的=
    在这里插入图片描述
图5 istore_1

++a

++a代码。

class A{
    public static void main(String argc[]){
         int a=0;
        a=++a;
        System.out.println(a);//1
    }
}

使用javap -verbose反汇编的结果。

 0: iconst_0
         1: istore_1
         2: iinc          1, 1 // 先加
         5: iload_1 // 后用
         6: istore_1 // 算符=
         7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        10: iload_1
        11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        14: return

例子
public static void main(String argc[]){
int j=0;
for(int i=0;i<100;++i){
j=j++;
}
System.out.println(j);
}
这个例子的值为0

总结

++a。先增有用。增是直接操作局部变量表中的a,让a的值加1(iinc操作的不是操作数栈,而是局部变量表)。用是将局部变量表中的a的值放入操作数栈定。
a++。先用后增。用是将局部变量表中a的值放入操作数栈顶,增是将局部变量表中a的值加一。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值