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
添加回答
舉報