如何在Java中複制對象?
考慮下面的代碼:
DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'
DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'
dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'
是以,我想複制dum到dumtwo并且更改dum而不影響dumtwo。但是上面的代碼沒有做到這一點。當我更改時dum,也會發生相同的更改dumtwo。
我想,當我說時dumtwo = dum,Java僅複制參考。那麼,有什麼方法可以建立的新副本dum并将其配置設定給dumtwo?
高分回答:
建立一個副本構造函數:
class DummyBean {
private String dummy;
public DummyBean(DummyBean another){
this.dummy = another.dummy; // you can access
每個對象都有一個克隆方法,可用于複制對象,但不要使用它。建立類和執行不正确的克隆方法太容易了。如果您要這樣做,請至少閱讀Joshua Bloch在Effective Java中要說的話。
高分回答:
基本: Java中的對象複制。
讓我們假設一個對象- obj1,它包含兩個對象,containedObj1和containedObj2。
在此處輸入圖檔說明
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcBnYldHL0FWby9mZvwVPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsAjMfd3bkFGazxCMx8VesATMfhHLlN3XnxCMz8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PwJWZ35SO3YzN1UjMmFTY5gzN4kDNzYzX5ADMwADM1EzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.webp)
淺表複制:
淺表複制建立instance相同類的新表,并将所有字段複制到新執行個體并傳回它。對象類提供了一種clone方法,并提供了對淺表複制的支援。
在此處輸入圖檔說明
深度複制:
深度複制是将對象及其引用的對象一起複制時發生的。下圖顯示了obj1在其上執行深度複制之後的情況。不僅已obj1被複制,而且包含在其中的對象也已被複制。我們可以Java Object Serialization用來制作深層副本。不幸的是,這種方法也存在一些問題(詳細示例)。
在此處輸入圖檔說明
可能的問題:
clone難以正确實施。
最好使用防禦性複制,複制構造函數(如@egaga回複)或靜态工廠方法。
如果您有一個對象,就知道它有一個公共clone()方法,但是在編譯時卻不知道該對象的類型,那麼您就遇到了問題。Java有一個名為的接口Cloneable。在實踐中,如果要建立對象,則應實作此接口Cloneable。Object.clone是protected,是以我們必須使用公共方法覆寫它,以便對其進行通路。
當我們嘗試對複雜對象進行深度複制時,會出現另一個問題。假設所有成員對象變量的方法也都進行深層複制,那麼進行假設的風險太大。您必須控制所有類中的代碼。clone()