我有以下代码:

public class Tests {
    public static void main(String[] args) throws Exception {
        int x = 0;
        while(x<3) {
            x = x++;
            System.out.println(x);
        }
    }
}

我们知道他应该只写x++或x=x+1,但在x=x+ +时,它应该先把x归为自己,然后再加1。为什么x的值是0 ?

- - -更新

下面是字节码:

public class Tests extends java.lang.Object{
public Tests();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[])   throws java.lang.Exception;
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iconst_3
   4:   if_icmpge   22
   7:   iload_1
   8:   iinc    1, 1
   11:  istore_1
   12:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   15:  iload_1
   16:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   19:  goto    2
   22:  return

}

我会仔细阅读说明,试着理解……


当前回答

x++表达式求值为x。++部分影响求值之后的值,而不是语句之后的值。所以x = x++可以有效地转换成

int y = x; // evaluation
x = x + 1; // increment part
x = y; // assignment

其他回答

X = x++的工作方式如下:

首先,它计算表达式x++。对该表达式求值产生一个表达式值(即x在递增前的值),并使x递增。 之后,它将表达式值赋给x,覆盖增量值。

因此,事件的序列如下所示(这是一个实际的反编译字节码,由javap -c生成,带有我的注释):

   8:   iload_1         // Remember current value of x in the stack
   9:   iinc    1, 1    // Increment x (doesn't change the stack)
   12:  istore_1        // Write remebered value from the stack to x

作为比较,x = ++x:

   8:   iinc    1, 1    // Increment x
   11:  iload_1         // Push value of x onto stack
   12:  istore_1        // Pop value from the stack to x

自增操作符应用于要赋值的变量。那是自找麻烦。我相信你可以看到你的x变量的值,同时运行这个程序....这应该清楚了为什么循环永远不会结束。

其他人已经解释得很好了。我只包含了指向相关Java规范部分的链接。

X = x++是一个表达式。Java将遵循求值顺序。 它将首先计算表达式x++,该表达式将增加x并将结果值设置为x的前一个值。 然后它将表达式结果赋值给变量x。最后,x返回到它之前的值。

前缀表示法将在表达式求值之前增加变量。 后缀表示法将在表达式求值后增加。

但是“=”的操作符优先级比“++”低。

所以x = x + +;应评估如下

X准备分配(评估) x增加 x之前的值赋给x。

你不需要机器代码来理解发生了什么。

根据定义:

赋值操作符求右边表达式的值,并将其存储在临时变量中。 1.1. x的当前值被复制到这个临时变量中 1.2. X现在是递增的。 然后将临时变量复制到表达式的左侧,也就是x !这就是为什么原来的x值又被复制到自身。

这很简单。