本问题已经有最佳答案,请猛点这里访问。
我在理解Java中"深层复制"的概念时遇到了困难。
假设我有一个带有各种参数的"myClass"类。 我尝试编写一个方法"copy",它应该返回这样一个类的深层副本:
public myClass copy() {
myClass deepCopy = new myClass();
deepCopy.varA = varA;
deepCopy.varB = varB;
return deepCopy;
}
有人可以确认这确实是"深度复制"还是我做错了什么?
谢谢!
en.wikipedia.org/wiki/Clone_%28Java_method%29
你最好使用以大写字母开头的类名。
@Kent:但最好的解决方案是建议使用构造函数,而我需要一个名为copy的方法(我正在扩展一个抽象类)@ G-Man:
@DarioPanada你可以实现Cloneable,当然不仅是myClass而且还有varA,B的类。 你必须在克隆方法中处理集合案例。
如果您不想自己实施深层复制,那么您可以进行序列化。它确实实现了深度复制,隐式地和优雅地处理循环依赖。
有关Deep Copy,Clone和Shallow Copy的精彩文章可以在这里找到。
如果varA和VarB是基本类型,那么这只是一个深层复制。如果它们是引用类型,则新对象将指向这些类的原始实例。
实现深层复制的简单方法是通过序列化。 Apache commons lang为此提供了一个实用方法(SerializationUtils.clone(foo))。
但它确实要求所有对象都是可序列化的。
如果不是这种情况,XStream可用于深度克隆,只需极少的开发工作。
http://x-stream.github.io/
将对象与其引用的对象一起复制时,会发生深层复制。
如果假设MainObject1的MainObject1类型具有int类型的字段"field1",并且包含ContainObject类型的"ContainObject1"。当您对MainObject1执行深层复制时,将使用"field3"创建MainObject2,其中包含复制的值"field1"和"ContainObject2",其中包含复制的ContainObject1值。因此,对MainObject1中的ContainObject1所做的任何更改都将在MainObject2中not be reflected。
在您的实现中,如果您尝试模拟深层复制,那么您应该只有这两个变量:基本类型的类中的varA和varB。
深度复制当复制的对象包含其他对象时,将以递归方式复制其引用
在这里看到更多
除非:
类"myClass"仅包含varA和varB。
类"myClass"没有超类。
变量varA和varB是基本类型(即String,int,long,....)。否则你也必须对它们应用相同的复制过程。
观察以下程序的输出。
1>请参见不带clone()方法的输出。从以下程序中删除clone()方法。 (浅拷贝的例子)
2>使用clone()方法查看输出。 (深拷贝示例。请参阅ArrayList对象的输出)
import java.util.ArrayList;
import java.util.List;
public class DeepCopy implements Cloneable {
private List 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();
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(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;
}
}
该方法可以称为复制吗?
来自Object类的clone()继承方法为变量(如int,long,boolean)隐式执行深度复制,除了像ArrayList这样的其他类(例子)。 所以最好使用clone()方法(类应该实现Cloneable接口)以避免自己编码。 在上面我给出的答案中,你必须覆盖clone(),在那些你陷入ArrayList类型的对象中,这些对象没有被clone()方法深度复制。 因此,重写clone()方法并进行一些编码以再次复制那些ArrayList对象及其内容。