谁能给我解释一下这种行为?
首先,我认为答案是 511 + 512(如果 j += j++ 意味着 j = j + (j+1))
我怎样才能证明答案为零?
public class Test
{
public static void main(String[] args)
{
int i = 0;
int j = 0;
for (i = 0, j = 0; i < 10; i++)
{
j += j++;
System.out.println("i = " + i + " >> " + j);
}
System.out.println(j);
}
}
> java Test
i = 0 >> 0
i = 1 >> 0
i = 2 >> 0
i = 3 >> 0
i = 4 >> 0
i = 5 >> 0
i = 6 >> 0
i = 7 >> 0
i = 8 >> 0
i = 9 >> 0
0
因为,j++
,表示求值后递增,而j+=x
表示j=j+x
,所以j
计算后变为 j+1
j=j+j
为零(加法结果为 0) 经过本次加法运算后,j 递增j++,但在此之后,加法结果用其值 0 覆盖了递增的 j 值。
看看这个,假设j=0;
j += j++
j++
增量将在读取j
值后执行,目前为0
。
所以它转化为:
1) read the first value for add operation - the value of j is 0 so we have add(0, ?)
2) read the second value for add operation `j++` is first evaluated to 0
so we have now add(0,0),
then j is incremented by 1, but it has this value for a very short time:
3) execute the add(0,0) operation, the result is 0 and overrides the incrementation done in previous setep.
4) finally the j is 0
所以在这种情况下,j 会在很短的时间内变为 1,但之后很快就会被覆盖。
结论是数学上j += j++;
最终只变成j = j + j;
在您的 for 循环中,这种情况会重复每个循环执行,最初 j 为 0,因此它会永远保持这种状态,在每次循环运行中都会在很短的时间内闪烁到 1。
也许您可以使 j 可变,然后在评估此 j += j++;
期间由其他线程在循环中读取它。读取线程可能会暂时看到 j 变为 1,但这是不确定的,在我的例子中,我使用这个简单的测试程序看到了这种情况:
public class IncrementationTest {
public static void main(String[] args) {
new IncrementationTest().start();
}
private volatile int j;
private void start() {
new Thread() {
@Override
public void run() {
while (true) {
System.out.println(j);
}
}
}.start();
while (true) {
j += j++;
}
}
}
输出是:
...
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
...
在我的机器上,似乎经常有幸读取中间值 1 以评估 j += j++