任何人都可以向我解释这种行为吗?
首先,我认为答案是 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+j
之后,j
变为j+1
,j 递增 j ++,但是之后,加法结果覆盖其递增的值 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,所以它永远保持这样,在每个循环运行中闪烁一个很短的时间。
也许你可以使 j volatile,然后在这个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++
因为当您执行a = b + c
时,您首先读取b
和c
,然后计算值。
此外,j++
means 返回 j 的当前值,然后将其递增 1。
在你的情况下,因为你做j = j + j++
你首先读取j
,然后你再次读取j
并返回j
的值。
你读到 j =0
你又读了 j =0
您计算j = j + 1
但是,现在您计算j = 0 + 0
并覆盖该值
所以在迭代结束时,j
的值没有改变。它仍然是 0。每次迭代都是如此,这就是为什么j
的值永远不会改变。
出现问题是因为 'j ++',如果在语句中使用,则以以下格式工作-
首先在语句中使用j
的值
然后增加j
的值。
在你的情况下,当你做j += j++
会发生什么-
首先,j
的值在语句中使用,因此j++
返回要在语句中使用的0
,我们计算了要分配给j
(尚未分配)的0 + 0
。
j
的增量值被分配给j
,即j
现在变为1
。
将从步骤 1 计算的值 0 分配给j
,因此j
再次变为0
。
后递增运算符是做什么的?操作完成后递增。
Nowj += j++;
这里的j
是0
,所以0 += 0
是0
。
该值被覆盖,因此j
永远保持0
。
现在让我们尝试预增量。
j + = ++ j;
输出:
i = 0 >> 1 // 0 + 1
i = 1 >> 3 // 1 + 2
i = 2 >> 7 // 3 + 4
i = 3 >> 15
i = 4 >> 31
i = 5 >> 63
i = 6 >> 127
i = 7 >> 255
i = 8 >> 511
i = 9 >> 1023
有意义吗?
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(66条)