i++ ,++i,i=i++的问题

      int i=0;
      i=i++;
      结果i是多少?
      这是一个经常被提及的问题,答案一直五花八门。
      具体测试一下以说明问题:
      代码1:
  1. public class Test{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          i=i++;
  5.          System.out.println(i);
  6.     }
  7. }
     结果i依然是0.分析其反编译后的代码:
    
  1. public static void main(java.lang.String[]);
  2.   Code:
  3.    0:   iconst_0     //0放到栈顶
  4.    1:   istore_1    //把栈顶的值保存到局部变量1,也就是i中
  5.    2:   iload_1     //把i的值放到栈顶,也就是说此时栈顶的值是0
  6.    3:   iinc    11  //注意这个指令,把局部变量1,也就是i,增加1,这个指令不会导致栈的变化,也就是说局部变量1,即i此时为1了。
  7.    6:   istore_1     //把栈顶的值(0)保存到局部变量1,也就是让i为0了,所以最后i为0
  8.    7:   getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  9.    10:  iload_1
  10.    11:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  11.    14:  return
值得注意到是i被修改了两次,第一次是i++;i变为1,最后一次是i=0;所以结果i是0
代码2:
  1. public class Test2{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          int j=0;
  5.          j=i++;
  6.          System.out.println(i);
  7.          System.out.println(j);
  8.     }
  9. }
这个结果肯定都知道,i是1,j是0.同样看反编译之后的代码:
  1. public static void main(java.lang.String[]);
  2.   Code:
  3.    0:   iconst_0
  4.    1:   istore_1     //i=0
  5.    2:   iconst_0
  6.    3:   istore_2     //j=0
  7.    4:   iload_1      //把i的值放到栈顶,也就是说此时栈顶的值是0
  8.    5:   iinc    11  //局部变量1加1,也就是让i++了,此时i已经是1了,上面说过,此指令不会导致栈变化
  9.    8:   istore_2     //把栈顶的值(注意是0)存入局部变量2,也就是j中,所以j=0
  10.    9:   getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  11.    12:  iload_1
  12.    13:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  13.    16:  getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  14.    19:  iload_2
  15.    20:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  16.    23:  return
很明显可以看出,java是先把i的值取出来放到栈顶,我们可以认为是引入了第三个变量int k=i;然后i++,这时候i为1了,然后让j=k;也就是0.结论,i的++运算是在对j这个变量的赋值之前完成的。

代码3:
  1. public class Test3{
  2.     public static void main(String[] args){
  3.          int i=0;
  4.          int j=0;
  5.          j=++i;
  6.          System.out.println(i);
  7.          System.out.println(j);
  8.     }
  9. }
结果大家也都知道,i=1,j=1
看操作过程:
  1. public static void main(java.lang.String[]);
  2.   Code:
  3.    0:   iconst_0   
  4.    1:   istore_1    //i=0
  5.    2:   iconst_0
  6.    3:   istore_2     //j=0
  7.    4:   iinc    11   //局部变量i加1,这时候i变成1了 。
  8.    7:   iload_1     //把i的值放到栈顶,栈顶的值是1
  9.    8:   istore_2    //j=1
  10.    9:   getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  11.    12:  iload_1
  12.    13:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  13.    16:  getstatic   #2//Field java/lang/System.out:Ljava/io/PrintStream;
  14.    19:  iload_2
  15.    20:  invokevirtual   #3//Method java/io/PrintStream.println:(I)V
  16.    23:  return
对比代码2和代码3,关键的差别就是 iload_1   个 iinc这两条指令的位置变了。

    最后把iinc指令介绍一下:

iinc

Operation

Increment local variable by constant  给局部变量加上一个常量的值

Format

iinc
index
const

Forms

iinc = 132 (0x84)

Operand Stack

No change   操作数栈无变化

Description

The index is an unsigned byte that must be an index into the local variable array of the current frame (§3.6). The const is an immediate signed byte. The local variable at index must contain an int. The value const is first sign-extended to an int, and then the local variable at index is incremented by that amount.

Notes

The iinc opcode can be used in conjunction with the wide instruction to access a local variable using a two-byte unsigned index and to increment it by a two-byte immediate value.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值