j+;=j++;你喜欢Java吗?
有人能给我解释一下这种行为吗?j+;=j++;你喜欢Java吗?,java,Java,有人能给我解释一下这种行为吗? 首先,我认为答案是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++;
首先,我认为答案是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
公共类测试
{
公共静态void main(字符串[]args)
{
int i=0;
int j=0;
对于(i=0,j=0;i<10;i++)
{
j++=j++;
System.out.println(“i=“+i+”>>”+j);
}
系统输出println(j);
}
}
>java测试
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++;
开始时,j=0
,然后j++
表示j
将在下一次迭代中递增。但是,在下一次迭代之前,您将0
分配到j
。
因此
j
被重新分配到0
因为j++
表示求值后的增量,j+=x
表示j=j+x
,所以j
在求值j=j+j
后变为j+1
,求值后为零(加法结果为0),计算此加法后,j增加j++,但在此之后,加法结果将覆盖增加的j值,其值为0
看看这个,假设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++
后增量运算符的作用是什么?操作完成后的增量
现在j++=j++代码>
当将j
添加到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
有意义吗?因为当您执行a=b+c
时,您首先读取b
和c
,然后计算值
另外,j++
表示返回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
使用+=
,根据:
对左侧进行求值,并生成对变量的引用
然后确定该变量的当前值
对右侧进行评估j++
首先获取j
(0
)的值,然后将其递增。j++
的结果是增量之前的值,即0
将结果添加到步骤2中确定的值(0
),并分配给步骤1中确定的变量(j
)
因此,由于我们每次都将0
分配给j
,尽管后增量,最终结果是0
以下是规范的实际语言:
如果左侧操作数表达式不是数组访问表达式,则:
- 首先,对左侧操作数求值以生成变量。如果此计算突然完成,则赋值表达式也会因为相同的原因突然完成;不计算右侧操作数,也不进行赋值
- 否则,将保存左侧操作数的值,然后计算右侧操作数的值。如果此计算突然完成,则赋值表达式也会因为相同的原因突然完成,并且不会发生赋值
- 否则,左侧变量的保存值和右侧操作数的值将用于执行二进制