执行时(幕后)会发生什么?

int x = 7;
x = x++;

也就是说,当一个变量在一条语句中被递增并分配给自己时?我编译并执行了这个。即使在整个表述之后X仍然是7。在我的书里,它说x是递增的!


当前回答

声明:

x = x++;

等价于:

tmp = x;   // ... this is capturing the value of "x++"
x = x + 1; // ... this is the effect of the increment operation in "x++" which
           //     happens after the value is captured.
x = tmp;   // ... this is the effect of assignment operation which is
           //     (unfortunately) clobbering the incremented value.

简而言之,这个声明没有任何效果。

重点:

后缀自增/自减表达式的值是操作数在进行自增/自减操作之前的值。(在Prefix形式的情况下,值是操作后的操作数的值,) 赋值表达式的RHS在赋值给LHS之前被完全计算(包括任何增量、减量和/或其他副作用)。

注意,与C和c++不同,Java中表达式的求值顺序是完全指定的,没有平台特定的变化空间。编译器只允许重新排序操作,前提是从当前线程的角度来看,这不会改变执行代码的结果。在这种情况下,编译器将被允许优化掉整个语句,因为可以证明它是一个无操作。


如果还不明显的话:

"x = x++;"在任何程序中几乎都是错误的。 OP(对于最初的问题!)可能意味着“x++;”而不是“x = x++;”。 将auto inc/ decentation和赋值结合在一起的语句很难理解,因此无论其正确性如何,都应该避免使用。根本没有必要编写这样的代码。

希望像FindBugs和PMD这样的代码检查器会将这样的代码标记为可疑的。

其他回答

它在“x = x++;”后面递增。如果你写x = ++x;它就是8。

这是因为您使用了后增量操作符。 在下面的代码行中

x = x++;

实际发生的情况是,你将x的值赋给x, x++在x赋给x后对x加1,这就是后加操作符的工作方式。它们在语句执行之后工作。所以在你的代码中,x先被返回然后再被递增。

如果你有

x = ++x;

答案是8,因为你使用了前增量操作符。这将在返回x值之前先对值进行递增。

最简单的解释!

这是因为在操作数对其进行后加1之后,++意味着首先将值赋给变量,然后再加1。而如果你期望x值为8,那么你应该像下面提到的那样预先增加它:

x = x++;

等于

int tmp = x;
x++;
x = tmp;

像x = x++;表明你可能误解了++操作符的作用:

// original code
int x = 7;
x = x++;

让我们重写它来做同样的事情,基于删除++操作符:

// behaves the same as the original code
int x = 7;
int tmp = x; // value of tmp here is 7
x = x + 1; // x temporarily equals 8 (this is the evaluation of ++)
x = tmp; // oops! we overwrote y with 7

现在,让我们重写它(我认为)你想要的:

// original code
int x = 7;
x++;

这里的微妙之处在于,++操作符修改变量x,这与x + x等表达式不同,后者将计算为int值,但变量x本身不变。考虑一个像值得尊敬的for循环这样的结构:

for(int i = 0; i < 10; i++)
{
    System.out.println(i);
}

注意到里面的i++了吗?这是同一个算子。我们可以像这样重写这个for循环,它的行为是一样的:

for(int i = 0; i < 10; i = i + 1)
{
    System.out.println(i);
}

我还建议在大多数情况下不要在较大的表达式中使用++运算符。由于它在增量前和增量后(分别是++x和x++)修改原始变量时的微妙之处,因此很容易引入难以追踪的微妙错误。