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

int x = 7;
x = x++;

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


当前回答

当你为x重新赋值时,它仍然是7。尝试x = ++x,你会得到8个其他的

x++; // don't re-assign, just increment
System.out.println(x); // prints 8

其他回答

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

这意味着: x++不等于X = X +1

因为:

int x = 7; x = x++;
x is 7

int x = 7; x = x = x+1;
x is 8

现在看来有点奇怪:

int x = 7; x = x+=1;
x is 8

非常依赖于编译器!

根据从类文件中获得的Byte码,

这两种赋值都增加x,但不同之处在于将值压入堆栈的时间

在Case1中,Push发生在增量之前(然后稍后分配)(本质上意味着您的增量不做任何事情)

在Case2中,Increment首先发生(使其为8),然后压入堆栈(然后分配给x)

案例1:

int x=7;
x=x++;

字节代码:

0  bipush 7     //Push 7 onto  stack
2  istore_1 [x] //Pop  7 and store in x
3  iload_1  [x] //Push 7 onto stack
4  iinc 1 1 [x] //Increment x by 1 (x=8)
7  istore_1 [x] //Pop 7 and store in x
8  return       //x now has 7

案例2:

int x=7; 
x=++x;

字节码

0  bipush 7     //Push 7 onto stack
2  istore_1 [x] //Pop 7 and store in x
3  iinc 1 1 [x] //Increment x by 1 (x=8)
6  iload_1  [x] //Push x onto stack
7  istore_1 [x] //Pop 8 and store in x
8  return       //x now has 8

Stack在这里指的是操作数Stack, local: x index: 1 type: int

像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++)修改原始变量时的微妙之处,因此很容易引入难以追踪的微妙错误。

因为x++在将值赋值给变量后会增加值。 因此,在执行这一行时:

x++;

变量x仍然有原始值(7),但是在另一行再次使用x,例如

System.out.println(x + "");

结果是8。

如果您想在赋值语句中使用x的递增值,请使用

++x;

这将使x增加1,然后将该值赋给变量x。

(编辑) 不是x = x++,而是x++;前者将x的原始值赋给自己,所以它实际上在这一行上什么也不做。