2013-02-07 78 views
2

我正在研究一個保存和調用屏幕狀態的系統,這是我第一次搞這樣的東西,所以我不確定最好的東西有關這方面的方法是,但我現在將所有「PreviewMonitor」對象(大約40左右)存儲在數組列表中。問題是,當我創建一個名爲「allPreviewMonitors」的ArrayList的副本時,我最終得到一個ArrayList,其元素在更新原始元素時不斷變化。這幾乎就好像我正在處理原始的ArrayList,事實上,當我創建allPreviewMonitors的副本時,它應該是一個完全不同的ArrayList,其中包含元素及其狀態的「凍結」版本。爲什麼會發生這種行爲?如果需要,我可以顯示代碼,但我不確定這是否需要。ArrayList的副本不斷修改爲原始的值

回答

2

您只是將對象引用複製到ArrayList中。你需要自己複製對象。

在Java中,所有對象變量實際上都是引用變量。因此,代碼:

Myclass myObject = new Myclass(); 
Myclass otherObject = myObject; 

創建一個對象MYCLASS並存儲在參考變量myObject該MYCLASS對象的引用。然後它創建一個新的參考變量otherObject,並將參考數據(例如存儲器地址)從myObject複製到otherObject。這些現在指的是內存中的同一個對象。在這一點上,該行

myObject.myMethod(); 

有你在你的ArrayList中獲得什麼相同的結果

otherObject.myMethod(); 

是同一對象的不同引用。 你想要的是下列之一:

Myclass otherObject = myObject.clone(); // use the clone function 
// OR 
Myclass otherObject = new Myclass(myObject); // use a copy constructor 

如果你把你的對象爲使用clone()或拷貝構造函數,你的ArrayList將包含,以相同的拷貝引用,而不是引用相同的副本ArrayList中。

正如其他人所指出的那樣,只是把引用的副本被稱爲「淺拷貝」,同時使被稱爲被稱爲「深拷貝」

+1

我試過使用複製構造函數,但是這導致了相同的輸出。難道是因爲PreviewMonitor(我的對象)包含一個JButton對象,這正是我使用PreviewMonitor.getJButton()拉對象? –

+0

我也嘗試過以上的方法,但是當我修改克隆對象時,它也會反映到原來的一個,也不知道出了什麼問題。 –

4

一個Arraylist像所有Collections,只包含對象的引用。 僅複製列表是不夠的,您還必須在創建列表的副本時克隆()元素(或創建新元素,或使用複製構造函數)。

這稱爲製作「深度複製」,而您目前有一個「淺複製」。

+0

對象的副本究竟是如何去有關「克隆」PreviewMonitor對象。我認爲這可能是問題,所以我創建了一些東西來測試它,並在PreviewMonitor對象中創建了一個「克隆」方法,因爲我認爲它應該創建,但我不太確定如果我做對了。 public PreviewMonitor clone(){return this; } –

2

您需要確保您執行「深度複製」 - 即克隆PreviewMonitor對象。默認情況下,你只需做一個淺拷貝並複製對同一個對象的引用。

+0

我如何去「克隆」PreviewMonitor對象。我認爲這可能是問題,所以我創建了一些東西來測試它,並在PreviewMonitor對象中創建了一個「克隆」方法,因爲我認爲它應該創建,但我不太確定如果我做對了。 \t public PreviewMonitor clone(){ \t \t return this; \t} –

+0

我假設'PreviewMonitor'是你自己的對象之一。克隆過程取決於對象。你通常會調用clone()方法。有更多信息在http://en.wikipedia.org/wiki/Clone_(Java_method)。 – Andrew

0

要克隆,您不能只返回當前對象。您必須創建一個與當前對象具有相同值的新對象。換句話說,使用當前對象的類的構造函數並創建一個新對象。確保舊對象和新對象之間的屬性匹配。返回新對象並重復原始列表中的每個對象。

+0

我已經試過both'code」 \t \t爲(PreviewMonitor sourcePreviewMonitor:previewMonitors){ \t \t \t this.previewMonitors.add(新PreviewMonitor(sourcePreviewMonitor.getPos(),sourcePreviewMonitor.getJButton()的getX(),sourcePreviewMonitor.getJButton。 () \t \t \t \t \t .getY(),sourcePreviewMonitor.getJButton()。的getWidth(),sourcePreviewMonitor.getJButton()。的getHeight(),sourcePreviewMonitor.getColumn(), \t \t \t \t \t sourcePreviewMonitor.getRow() ,sourcePreviewMonitor.getRight())); \t \t} - 然後爲PreviewMonitor對象創建一個新的構造函數,使其獲得一個參數,另一個PreviewMonitor並將其傳入。 –

相關問題