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

Java 什么是浅克隆或深克隆更好?,java,cloning,Java,Cloning,我对java中的对象克隆有点困惑。浅层克隆和深层克隆的主要区别是什么 哪一个更好 浅层克隆和深层克隆的主要区别是什么 浅层克隆复制树的顶层,但从该顶层指向的任何内容(例如对象属性)仍由两个副本共享。深度克隆复制树的所有级别,在源和副本之间不留下任何链接 例如,假设您有一个Person对象(a)具有配偶属性,这也是一个Person对象: +-------------+ | Person: a | +-------------+ | name: "Joe" | |

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

哪一个更好

浅层克隆和深层克隆的主要区别是什么

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

例如,假设您有一个
Person
对象(a)具有
配偶
属性,这也是一个
Person
对象:

+-------------+ | Person: a | +-------------+ | name: "Joe" | | spouse |-------------->+---------------+ +-------------+ | Person | +---------------+ | name: "Mary" | +---------------+ 如果你进行深度克隆,你不仅要将
a
克隆到
b
,还要将
a.party
克隆到
b.party
,这样每个人都有自己的副本

+-------------+ |人:a| +-------------+ |姓名:“乔”| |配偶|----------------->+---------------+ +-------------+|人| +---------------+ +-------------+|姓名:“玛丽”| |人:b|+---------------+ +-------------+ |姓名:“乔”| |配偶|----------------->+---------------+ +-------------+|人| +---------------+ |姓名:“玛丽”| +---------------+ 哪一个更好


都不是。两者都有用途,而且都可能被误用。

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

但是,不能说哪一个更好。

这取决于你想要实现什么:

如果您想要一个指向相同对象的引用列表,并且只想以某种方式避免 ConcurrentModificationException比您可以使用浅层克隆更有效

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

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

深度克隆

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

您也可以考虑复制构造函数

如果你问哪一个更好,这取决于你一直在寻找什么样的行为


关于克隆的简要介绍:

考虑b类已从A类克隆。。 如果对某个类所做的任何更改都会影响b类,那么它就是卷影复制。如果对某个类所做的任何更改都不会影响b类,那么它就是深度克隆。。 因为在阴影中克隆b类指向a类。它共享相同的内存位置。。 在深度克隆中,将创建单独的副本。。
这意味着a类和b类将有单独的内存位置。

嗯,浅层克隆和深层克隆都很有用。如果您的单个类实例不包含任何其他类的引用,则最好进行浅拷贝,但如果有其他类的实例被我们的具体类使用,则我们应选择深度克隆,否则无法实现完全克隆。

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

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

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

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

要了解更多信息,您可以查看

的可能副本。这个有你想要的细节。你是用手还是用工具创建这些图表的?@AdamArold:我很傻,是用手做的。我可能应该用或类似的,我明白了。它们看起来真的很漂亮,我还以为用了什么工具呢。哈哈:到目前为止我还没用过。这不对吗?它提到了影子复制,从解释上看,他的意思似乎是复制对象,而不是克隆它。。? +-------------+ | Person: a | +-------------+ | name: "Joe" | | spouse |-------------->+---------------+ +-------------+ | Person | +---------------+ +-------------+ | name: "Mary" | | Person: b | +---------------+ +-------------+ | name: "Joe" | | spouse |-------------->+---------------+ +-------------+ | Person | +---------------+ | name: "Mary" | +---------------+
public Person clone() throws CloneNotSupportedException {
    Person clonedObj = (Person) super.clone();
    clonedObj.city = this.city.clone();
    return clonedObj;
}