3 回答
TA贡献1830条经验 获得超3个赞
注意:最初我在本答案中发布了C#代码用于说明,因为C#允许您int通过引用传递参数和ref关键字。我决定使用MutableInt我在Google上找到的第一个类来实际使用合法的Java代码来更新它,以便对refC#中的内容进行近似处理。我无法确定这是否有助于或伤害答案。我会说我个人没有做过那么多Java开发; 所以我知道可能有更多的惯用方法来说明这一点。
也许如果我们写出一个方法来做相同的事情x++,它会使这更清楚。
public MutableInt postIncrement(MutableInt x) {
int valueBeforeIncrement = x.intValue();
x.add(1);
return new MutableInt(valueBeforeIncrement);
}
对?增加传递的值并返回原始值:这是postincrement运算符的定义。
现在,让我们看看您的示例代码中这种行为是如何发挥作用的:
MutableInt x = new MutableInt();
x = postIncrement(x);
postIncrement(x)做什么?增量x,是的。然后返回什么x 是增量之前。然后将此返回值分配给x。
因此,赋值的值的顺序x为0,然后是1,然后是0。
如果我们重写上述内容,这可能会更清楚:
MutableInt x = new MutableInt(); // x is 0.
MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.
x = temp; // Now x is 0 again.
当你x在上面的作业的左侧替换为y“你可以看到它首先递增x,然后将它归因于y” 这一事实时,你固定的事实让我感到困惑。它不是x被分配给y; 它是以前赋予的价值x。实际上,注入y使事情与上面的场景没有什么不同; 我们只是得到:
MutableInt x = new MutableInt(); // x is 0.
MutableInt y = new MutableInt(); // y is 0.
MutableInt temp = postIncrement(x); // Now x is 1, and temp is 0.
y = temp; // y is still 0.
所以很清楚:x = x++有效地不会改变x的值。它总是使x的值为x 0,然后是x 0 + 1,然后再次为x 0。
更新:顺便说一句,为了避免你怀疑x在上面的例子中增加操作和赋值之间的分配是1“之间”,我已经把一个快速演示组合在一起来说明这个中间值确实“存在”,尽管它会永远不会在执行线程上“看到”。
演示调用x = x++;循环,而单独的线程连续打印x控制台的值。
public class Main {
public static volatile int x = 0;
public static void main(String[] args) {
LoopingThread t = new LoopingThread();
System.out.println("Starting background thread...");
t.start();
while (true) {
x = x++;
}
}
}
class LoopingThread extends Thread {
public @Override void run() {
while (true) {
System.out.println(Main.x);
}
}
}
以下是上述程序输出的摘录。注意1和0的不规则出现。
启动后台线程...
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
0
1
添加回答
举报