2013-03-22 103 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/