3 回答

TA貢獻(xiàn)1830條經(jīng)驗(yàn) 獲得超3個(gè)贊
注意:最初我在本答案中發(fā)布了C#代碼用于說明,因?yàn)镃#允許您int通過引用傳遞參數(shù)和ref關(guān)鍵字。我決定使用MutableInt我在Google上找到的第一個(gè)類來實(shí)際使用合法的Java代碼來更新它,以便對(duì)refC#中的內(nèi)容進(jìn)行近似處理。我無(wú)法確定這是否有助于或傷害答案。我會(huì)說我個(gè)人沒有做過那么多Java開發(fā); 所以我知道可能有更多的慣用方法來說明這一點(diǎn)。
也許如果我們寫出一個(gè)方法來做相同的事情x++,它會(huì)使這更清楚。
public MutableInt postIncrement(MutableInt x) {
int valueBeforeIncrement = x.intValue();
x.add(1);
return new MutableInt(valueBeforeIncrement);
}
對(duì)?增加傳遞的值并返回原始值:這是postincrement運(yùn)算符的定義。
現(xiàn)在,讓我們看看您的示例代碼中這種行為是如何發(fā)揮作用的:
MutableInt x = new MutableInt();
x = postIncrement(x);
postIncrement(x)做什么?增量x,是的。然后返回什么x 是增量之前。然后將此返回值分配給x。
因此,賦值的值的順序x為0,然后是1,然后是0。
如果我們重寫上述內(nèi)容,這可能會(huì)更清楚:
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.
當(dāng)你x在上面的作業(yè)的左側(cè)替換為y“你可以看到它首先遞增x,然后將它歸因于y” 這一事實(shí)時(shí),你固定的事實(shí)讓我感到困惑。它不是x被分配給y; 它是以前賦予的價(jià)值x。實(shí)際上,注入y使事情與上面的場(chǎng)景沒有什么不同; 我們只是得到:
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++有效地不會(huì)改變x的值。它總是使x的值為x 0,然后是x 0 + 1,然后再次為x 0。
更新:順便說一句,為了避免你懷疑x在上面的例子中增加操作和賦值之間的分配是1“之間”,我已經(jīng)把一個(gè)快速演示組合在一起來說明這個(gè)中間值確實(shí)“存在”,盡管它會(huì)永遠(yuǎn)不會(huì)在執(zhí)行線程上“看到”。
演示調(diào)用x = x++;循環(huán),而單獨(dú)的線程連續(xù)打印x控制臺(tái)的值。
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的不規(guī)則出現(xiàn)。
啟動(dòng)后臺(tái)線程...
0
0
1
1
0
0
0
0
0
0
0
0
0
0
1
0
1
添加回答
舉報(bào)