2013-03-22 104 views
3

我很難理解Java中「深層複製」的概念。如何深度複製

假設我有一個帶有各種參數的類「myClass」。我試着寫本該是回到這種類的深層副本作爲方法「複製」:

public myClass copy() { 

    myClass deepCopy = new myClass(); 
    deepCopy.varA = varA; 
    deepCopy.varB = varB; 
    return deepCopy; 

} 

有人可以確認這是否確實是「深複印」如果我做錯了什麼?

謝謝!

+0

http://en.wikipedia.org/wiki/Clone_%28Java_method%29 – 2013-03-22 13:07:33

+0

接着,從大寫字母您更好地使用類名。 – 2013-03-22 13:08:55

+0

@Kent:但是最好的解決方案是建議使用構造函數,而我需要一個名爲copy的方法(我正在擴展一個抽象類)@ G-Man: – MrD 2013-03-22 13:30:45

回答

1

如果你不想實現深拷貝,那麼你可以去serialization。它確實隱式地實現了深層複製,並且正常地處理循環依賴。

關於Deep Copy,Clone和Shallow Copy的不錯文章可以在here找到。

0

只有:

  • 類 「MyClass的」 僅包含瓦拉和varB。
  • 「myClass」類沒有超類。
  • 變量varA和varB屬於基本類型(即String,int,long,...)。否則,你也必須對它們應用相同的複製過程。
0

在深拷貝當複製對象包含其引用複製了一些其他對象遞歸

多見於here

-1

遵循以下程序的輸出。
1>請參閱不帶clone()方法的輸出。從下面的程序中刪除clone()方法。 (淺拷貝示例)
2>使用clone()方法查看輸出。 (實施例深層副本。參見ArrayList對象的輸出)

import java.util.ArrayList; 
import java.util.List; 

public class DeepCopy implements Cloneable { 
    private List<String> hobbiesList; 
    private int age; 
    private String name; 
    private float salary; 

    public static void main(String[] args) throws CloneNotSupportedException { 
     DeepCopy original = new DeepCopy(); 
     original.name="AAA"; 
     original.age=20; 
     original.salary=10000; 
     original.hobbiesList = new ArrayList<String>(); 
     original.hobbiesList.add("Cricket"); 
     original.hobbiesList.add("Movies"); 
     original.hobbiesList.add("Guitar"); 
     original.hobbiesList.add("Eating"); 

     DeepCopy cloned = (DeepCopy) original.clone(); 
     System.out.println("original:="+original); 
     System.out.println("cloned :="+cloned); 
     System.out.println("After adding two more hobbies in 'original' which untimately reflected in 'cloned'"); 
     cloned.name="BBB"; 
     cloned.age=27; 
     cloned.salary=18237; 
     cloned.hobbiesList.add("Trecking"); 
     System.out.println("original  :="+original); 
     System.out.println("cloned changed:="+cloned); 
    } 
    @Override 
    protected Object clone() throws CloneNotSupportedException { 
     DeepCopy clone = (DeepCopy)super.clone(); 
     clone.hobbiesList = new ArrayList<String>(clone.hobbiesList); 
     return clone; 
    } 
    @Override 
    public String toString() { 
     return "My name is (String)"+name + " having age (int)"+age+". I earned (float)"+salary+" and hobbies are (ArrayList)"+hobbiesList; 
    } 
} 
+0

該方法可以稱爲複製嗎? – MrD 2013-03-22 13:32:11

+0

clone()從Object類繼承的方法對像int,long和boolean類型的變量(如ArrayList(示例)等其他類)隱式地複製深度副本。所以最好使用clone()方法(類應該實現Cloneable接口)以避免自己編碼。在上面我給出的答案中,你必須重寫clone(),在那些你不能被clone()方法深度拷貝的ArrayList類型的對象中。因此,重寫clone()方法並執行一些編碼以再次複製那些ArrayList對象及其內容。 – AmitG 2013-03-22 13:37:38

0

當對象與其所引用的對象一起復制時,會發生深層副本。

如果假設存在MainObject類型的MainObject1類型,其中int類型爲"field1",ContainObject類型爲"ContainObject1"。當您執行MainObject1的深層副本時,將使用包含複製值「field1」和「ContainObject2」(包含ContainObject1的複製值)的「field3」創建MainObject2。因此,對MainObject1中的ContainObject1所做的任何更改將在MainObject2中爲not be reflected

在您的實現中,如果您試圖模擬深度複製,那麼您應該只有這兩個變量:varAvarB在您的原始類型類中。

0

如果varA和VarB是原始類型,這隻會是一個深層複製。如果它們是引用類型,則新對象將指向與原始類相同的這些類的實例。

實現深層複製的簡單方法是通過序列化。 Apache commons lang爲此提供了一種實用方法(SerializationUtils.clone(foo))。

但它要求所有的對象都是可序列化的。

如果情況並非如此,只需最少的開發工作即可將XStream用於深度克隆。

http://x-stream.github.io/