java中j_j + = j ++在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++;

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++表示求值后的增量,而j+=x表示j=j+x,所以j在求和后的j=j+j为零(加法结果为0)后,成为j+1, 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 + = 0"没有区别吗? 这似乎有点违反直觉:(

@ jeta.Investigator在j为0的情况下是,在其他情况下不是j + = j ++; 最后变成j = j + j;

因为当您执行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以在语句中使用,并且我们已经计算了0 + 0分配给j(不是尚未分配)。

j的增量值分配给j,即j现在变为1。

从步骤1计算得出的值为0的值分配给j,因此j再次变为0。

What does a post-increment operator do? Increment after the operation is completed.

现在j += j++;

将j添加到j时,此处为0。因此0 += 0将是0。

The value is over-rided so j stays 0 forever.

让我们现在尝试预增量。

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

说得通?

但是在原始问题中添加后不应该j递增?

它被压倒了。:)

对于JLS§15.26.2,使用+=:

对左侧进行求值并产生对变量的引用。

确定该变量的当时值。

评估右侧。 j++首先获取j(0)的值,然后将其递增。 j++的结果是增量之前的值,即0。

将结果加到在步骤2中确定的值(0),并分配给在步骤1中确定的变量(j)。

因此,由于我们每次都将0分配给j,所以尽管后增加,最终结果还是0。

这是规范的实际语言:

If the left-hand operand expression is not an array access expression, then:

First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.

Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.

问题在这里

j += j++;

首先,j = 0,然后j++表示j将在下一次迭代中递增。但是,在下一次迭代之前,您要将0分配给j。

因此j被重新分配给0。

其用户实际问题

@SergeyMaksimenko,我正在更新我的答案,与此同时有很多反对意见...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值