从字节码角度分析:x=0;x=x++;结果为x=0;

源码:

public class test {
    public static void main(String[] args) {
        int i=0;
        int x=0;
        while(i<10){
            x=x++;
            i++;
        }
        System.out.println(x);//0
    }
}

字节码:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=3, args_size=1
         0: iconst_0
         1: istore_1
         2: iconst_0
         3: istore_2
         4: iload_1
         5: bipush        10
         7: if_icmpge     21
        10: iload_2
        11: iinc          2, 1
        14: istore_2
        15: iinc          1, 1
        18: goto          4
        21: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
        24: iload_2
        25: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
        28: return
      LineNumberTable:
        line 3: 0
        line 4: 2
        line 5: 4
        line 6: 10
        line 7: 15
        line 9: 21
        line 10: 28
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      29     0  args   [Ljava/lang/String;
            2      27     1     i   I
            4      25     2     x   I
      StackMapTable: number_of_entries = 2

此处我就不详细讲解指令,若不懂指令意思的请查看我上一篇博客,并且上一篇博客有图解,理解起来也更加容易:从字节码角度分析a++相关问题

1)iconst_0:

  • 将常量0入栈
  • JVM中 iconst 是一个入栈指令,其作用是用来将 int 类型的数字。
  • 取值在 -1 到 5 之间的整数是使用 iconst_xx 来表示的。
  • 当取值等于 -1 时,采用 iconst_m1 指令,当取值在 0 到 5 之间时,分别对应 iconst_0、iconst_1、iconst_2、iconst_3、iconst_4、iconst_5 这几个指令。

2)istore_1:

  • 将操作数栈顶数据弹出,存入局部变量表的 slot 1,即 i 变量中:i=0;

3)iconst_0: 同上
4)istore_2:

  • 将操作数栈顶数据弹出,存入局部变量表的 slot 2,即 x 变量中: x=0;

5)iload_1:

  • 将局部变量表的slot 1中的数据读取到操作数栈中,即读取 i 变量的值

6)bipush 10:

  • 将 10 压入操作数栈

7)if_icmpge 21:

  • 栈顶下一个元素的值是否大于等于栈顶元素值,即 i 是否>=10
  • 若 i>=10 为真,则跳转到21号语句执行。
  • 若 i>=10 为假,则继续执行下一条语句。

8)iload_2:

  • 将局部变量表的slot 2中的数据读取到操作数栈中,即将变量 x 的值0读入栈中。

9)iinc 2,1:

  • 将局部变量表中的solt 2中的数据值加1,即变量 x 的值加1:x=1;
  • 注意:操作数栈中存储的只是一个值而已,不是变量 x 的引用;所以,局部变量表中
    x的值加1,不会影响到操作数栈中的值,即操作数栈中的值不会加1。定义:iinc 指令是直接在局部变量 slot 上进行运算。

10) istore_2:

  • 将操作数栈顶数据弹出,存入局部变量表的 slot 2。
  • 注意:此时操作数栈顶的元素是第8号语句读入的 x 变量值,即此时栈顶元素的值为0; 但此时局部变量表中的slot 2 的值在第9号语句加1了,即此时 x 的值为1; 将栈顶元素存入局部变量表 slot 2 中,就相当于将 x变量的值重新赋值为0了,即 x=0;

11) iinc 1,1:

  • 将局部变量表中的solt 1中的数据值加1,即变量 i 的值加1:i=1;

12) goto 4:

  • 跳转到4号语句执行。

综上所述: 只要在第9号语句执行了自增(iinc 2,1),都会在第10号语句将 x 的重新赋值为0。
原理: iinc 指令是直接在局部变量 slot 上进行运算;不会影响到操作数栈中的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值