2017-03-06 75 views
0

在此循環中有一個名爲pawn的變量,但該循環使用該一個變量創建8個Pawn(s)。這怎麼可能?而且,我們能否區分從這個變量創建的每個棋子?使用相同的變量名稱在for循環中初始化多個對象時會發生什麼?

public void setUpChessPieces() { 
    for (int i = 0; i < ChessGame.EIGHT; i++) { 
     //param 1:row, param 2:col, param 3:player#, param4:chess piece color 
     Pawn pawn1 = new Pawn(1, i, 1, "white"); 
     //squares has a setPiece method 
     squares[1][i].setPiece(pawn1); 
    } 
} 
+0

變量「名稱」並不是真的那麼重要,對許多對象來說都不存在,* *在編譯代碼中幾乎不存在。如果一個對象被多個變量引用,哪一個代表這個對象的「名稱」?更重要的是*對象**引用***以及如何獲得它們。 –

回答

2

發生了什麼會是這樣一個簡短的廚師下降:

new Pawn(1, i, 1, "white"); 

的JVM分配在堆中的新對象。

Pawn pawn1 = new Pawn(1, i, 1, "white"); 

新分配對象的引用被分配給pawn1。把參考看作一個值,說「在堆中的這個地方查找對象」。

squares[1][i].setPiece(pawn1); 

setPiece正在通過引用Object來調用。

循環終止,pawn1「消失」。這隻意味着pawn1本身不再可用。對象本身被存儲在堆上,因此不會消失。這個過程重複完成,直到循環完成。

Object被銷燬的過程被稱爲垃圾收集,並且不影響任何仍在使用的對象(如引用存儲在pawn1中的對象)。

這些棋子如何區分?
感謝參考。每個對象都存儲在堆上的不同位置。所有人必須做的就是比較位置以注意差異(來自JVM內部的POV)。

2

當你說

squares[1][i].setPiece(pawn1); 

你保存你new創建的參考。每次撥打new時,您都會創建一個名爲pawn1的臨時參考號,但您可以通過前面提到的撥打電話setPiece來進行保存。只要squares有參考,它不是有資格進行垃圾回收。

+0

這意味着每個棋子都有不同的參考,這意味着我將能夠移動每個棋子嗎?換句話說,所有8個兵都不是同一個? – tragicProgrammer

+0

@tragicProgrammer如前所述,是的。那是對的。 –

2

這怎麼可能?

這是可能的,因爲在for循環的每次迭代中創建一個pawn實例。 pawn1只是創建的object的標識符。在for循環迭代中創建的每個對象都是存儲在堆內存中的獨立對象。

Pawn pawn1 = new Pawn(1, i, 1, "white"); 

而且是我們能夠區分這 從這個變量,創建每個棋子?

我們可以區分它們的基礎數據,而不是pawn1標識符。例如,如果每個pawn對象都覆蓋了toString()方法,並且要打印出來,您會發現它們是不同的對象,除非兩個不同的對象具有相同的基礎數據,那麼它們將具有相同的string表示形式。

0

變量只是一個指向對象的指針(或指向任何東西的null)。如果你有一個物理棋盤並用手指指向每個棋子,你可以用同一個指針指向16個不同的對象。在Java中是一樣的。

您可以稍後通過維護單獨的指針來檢索每個對象。您的代碼通過將pawn1指針的值複製到每個squares元素中來完成此操作。

循環結束時,pawn1指針(變量)超出範圍並消失,但squares引用保持在範圍內。

但是,如果您從squares替換值而不復制到之前對象的引用(指針)的某處,那麼將永遠丟失對該先前對象的最後一個引用,並且它將變得無法訪問。

對象不是「從[a]變量創建的」。它們是通過調用new(通常)創建的,並且返回指向結果對象的指針,大概是爲了賦值給變量或參與某些操作。您也可以丟棄最終的參考,但這可能是一個錯誤。

您可以創建一個對象,並將其引用分配給用於保存不同值的相同變量,就像您可以將不同值分配給任何非最終變量,基元或引用一樣。

相關問題