我对java中的对象克隆有点困惑。浅层克隆和深度克隆之间的主要区别是什么?
哪个好多了?
答案 0 :(得分:15)
浅层克隆和深度克隆之间的主要区别是什么?
浅层克隆复制树的顶层,但是从该顶层指向的任何内容(例如,对象属性)仍由两个副本共享。深度克隆复制树的所有级别,在源和副本之间不留任何链接。
例如,假设您有一个Person
对象(a),其spouse
属性也是Person
对象:
+-------------+ | Person: a | +-------------+ | name: "Joe" | | spouse |-------------->+---------------+ +-------------+ | Person | +---------------+ | name: "Mary" | +---------------+
如果您对a
b
进行浅克隆,则a
和b
都指向相同来自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)
嗯,浅层克隆和深度克隆都很有用。如果你有一个单独的类实例,它不包含任何其他类的引用,那么最好生成一个浅表副本,但如果有一些其他类的实例被我们的具体类使用,那么我们应该选择深度克隆,否则完成克隆无法实现。