什么是更好的浅或深克隆?

时间:2013-10-04 07:59:58

标签: java cloning

我对java中的对象克隆有点困惑。浅层克隆和深度克隆之间的主要区别是什么?

哪个好多了?

7 个答案:

答案 0 :(得分:15)

  

浅层克隆和深度克隆之间的主要区别是什么?

浅层克隆复制树的顶层,但是从该顶层指向的任何内容(例如,对象属性)仍由两个副本共享。深度克隆复制树的所有级别,在源和副本之间不留任何链接。

例如,假设您有一个Person对象(a),其spouse属性也是Person对象:

+-------------+
| Person: a   |
+-------------+
| name: "Joe" |               
| spouse      |-------------->+---------------+
+-------------+               | Person        |
                              +---------------+
                              | name: "Mary"  |
                              +---------------+

如果您对a b进行克隆,则ab都指向相同Person属性的强> spouse

+-------------+
| Person: a   |
+-------------+
| name: "Joe" |               
| spouse      |------+
+-------------+      |        
                     |
+-------------+      +------->+---------------+
| Person: b   |      +------->| Person        |
+-------------+      |        +---------------+
| name: "Joe" |      |        | name: "Mary"  |
| spouse      |------         +---------------+
+-------------+       

如果您执行克隆,则不仅要将a克隆到b,还要将a.spouse克隆到b.spouse,以便它们每个人最终都拥有自己的副本。

+-------------+
| Person: a   |
+-------------+
| name: "Joe" |               
| spouse      |-------------->+---------------+
+-------------+               | Person        |
                              +---------------+
+-------------+               | name: "Mary"  |
| Person: b   |               +---------------+
+-------------+       
| name: "Joe" |       
| spouse      |-------------->+---------------+
+-------------+               | Person        |
                              +---------------+
                              | name: "Mary"  |
                              +---------------+
  

哪个好多了?

都不是。两者都有用途,两者都可能被滥用。

答案 1 :(得分:3)

在浅层克隆中,克隆类不会复制其内部对象,但在深度克隆中,也会复制类的所有内部对象。 深度克隆的一个缺点似乎是序列化,这种克隆对象的序列化并不那么容易 然而,不能说哪个更好。

答案 2 :(得分:1)

浅拷贝: 通常克隆对象的方法,创建同一个类的新实例,并将所有字段复制到新实例并返回它。这只是浅薄的副本。

深度克隆

在大多数情况下,这是理想的行为。我们想要一个独立于原始的克隆,并且克隆中的更改不应该影响原始。

你也可以想到复制构造函数。

并且你的问题哪个会更好,这取决于你一直在寻找的行为。

关于克隆的简要介绍:http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/

答案 3 :(得分:1)

考虑从类中克隆了b类.. 如果对类进行的任何更改会影响b类,则它是卷影副本。如果类中所做的任何更改都不会影响b类,那么它将被称为深度克隆。 因为在阴影克隆中,b类指向一个类..它共享相同的内存位置。 在深度克隆中,将创建单独的副本。 这意味着一个类和一个类将具有单独的内存位置..

答案 4 :(得分:1)

这取决于您的要求,您需要一个内部指向相同对象的不同对象,或者您需要重复

浅层克隆Object.clone()方法提供的默认克隆策略。浅层克隆策略创建一个新实例,并将给定对象的所有字段复制到该新实例(它是原始实例或引用实例)。因此,在引用类型的情况下,只有引用位被复制到新实例,因此,两个对象的引用变量将指向同一个对象。

深度克隆顾名思义,深度克隆意味着克隆从一个对象到另一个对象的所有内容。要实现这一目标,您需要欺骗clone()方法提供自己的克隆策略。您可以通过在我们的对象层次结构中的每个引用类型中实现Cloneable接口和覆盖clone()方法,然后在对象的clone方法中调用super.clone()和这些clone()方法来实现。

public Person clone() throws CloneNotSupportedException {
    Person clonedObj = (Person) super.clone();
    clonedObj.city = this.city.clone();
    return clonedObj;
}

要了解更多信息,您可以查看Java Cloning and Types of Cloning (Shallow and Deep) in Details with Example

答案 5 :(得分:0)

这取决于你想要达到的目标:

如果你想要一个对相同对象的引用列表,只是想以某种方式避免 ConcurrentModificationException 比您可以使用浅层克隆。

如果你想要一大堆内部具有相同值的新对象,则需要深度克隆。

答案 6 :(得分:0)

嗯,浅层克隆和深度克隆都很有用。如果你有一个单独的类实例,它不包含任何其他类的引用,那么最好生成一个浅表副本,但如果有一些其他类的实例被我们的具体类使用,那么我们应该选择深度克隆,否则完成克隆无法实现。