【发布时间】:2013-10-11 03:41:51
【问题描述】:
我对 java 中的对象克隆有点困惑。浅克隆和深克隆的主要区别是什么?
哪个更好?
【问题讨论】:
-
How do I copy an object in Java? 的可能副本。 second answer 有您正在寻找的详细信息。
我对 java 中的对象克隆有点困惑。浅克隆和深克隆的主要区别是什么?
哪个更好?
【问题讨论】:
浅克隆和深克隆的主要区别是什么?
浅克隆复制树的顶层,但从顶层指向的任何内容(例如,对象属性)仍然由两个副本共享。深度克隆复制树的所有级别,在源和副本之间不留任何链接。
例如,假设您有一个带有spouse 属性的Person 对象(a),它也是一个Person 对象:
+--------------+
|人:一个 |
+--------------+
|姓名:“乔” |
|配偶|------------->+----------------+
+--------------+ |人 |
+---------------+
|名称:“玛丽” |
+---------------+
如果你对a 到b 进行浅 克隆,a 和b 都从它们的@ 指向相同 Person 987654330@属性:
+--------------+
|人:一个 |
+--------------+
|姓名:“乔” |
|配偶 |------+
+--------------+ |
|
+-------------+ +------->+----------------+
|人: b | +------->|人 |
+--------------+ | +---------------+
|姓名:“乔” | | |名称:“玛丽” |
|配偶 |------ +----------------+
+--------------+
如果您进行深度克隆,您不仅将a 克隆为b,而且将a.spouse 克隆为b.spouse,这样他们每个人最终都有自己的拥有副本。
+--------------+
|人:一个 |
+--------------+
|姓名:“乔” |
|配偶|------------->+----------------+
+--------------+ |人 |
+---------------+
+--------------+ |名称:“玛丽” |
|人: b | +---------------+
+--------------+
|姓名:“乔” |
|配偶|------------->+----------------+
+--------------+ |人 |
+---------------+
|名称:“玛丽” |
+---------------+
哪个更好?
两者都没有。两者都有用处,都可能被滥用。
【讨论】:
在浅克隆中,克隆的类不会复制其内部对象,但在深度克隆中,该类的所有内部对象也会被复制。
深度克隆的一个缺点似乎是序列化,这种克隆对象的序列化并不容易。
但是不能说哪个更好。
【讨论】:
这取决于你想要达到的目标:
如果你想要一个对相同对象的引用列表并且只是想以某种方式避免 ConcurrentModificationException 比你可以使用浅克隆。
如果您想要一大堆内部具有相同值的新对象,则需要深度克隆。
【讨论】:
浅拷贝: 通常克隆一个对象的方法,创建同一个类的一个新实例,并将所有字段复制到新实例并返回它。这不过是浅拷贝。
深度克隆
在大多数情况下,这是所需的行为。我们想要一个独立于原始版本的克隆,并且在克隆中进行更改不应影响原始版本。
你也可以考虑复制构造函数。
并提出你的问题,哪个会更好,这取决于你一直在寻找什么行为。
关于克隆的简要介绍:http://howtodoinjava.com/2012/11/08/a-guide-to-object-cloning-in-java/
【讨论】:
考虑 b 类是从一个类中克隆出来的.. 如果对一个类所做的任何更改影响了b类,那么它就是影子副本。如果对一个类所做的任何更改不影响b类,那么它被称为深度克隆。 因为在影子克隆中 b 类指向 a 类..它共享相同的内存位置.. 在深度克隆中,将创建单独的副本。 这意味着a类和b类将具有单独的内存位置..
【讨论】:
嗯,浅克隆和深层克隆都很有用。如果您有一个不包含任何其他类的引用的类实例,那么最好进行浅拷贝,但如果有一些其他类的实例被我们的具体类使用,那么我们应该选择深度克隆,否则完全克隆达不到。
【讨论】:
这取决于您的要求,您需要一个内部指向相同对象的不同对象,或者您需要一个重复的对象
浅克隆是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
【讨论】: