在java浅拷贝中是clone()吗?

java中的clone()是浅拷贝吗?

最终,这将获得Object的clone()方法(最上层的类),它创建与对象相同的类的新实例,并将所有字段复制到新实例(“浅拷贝”)。

我是从维基百科读到的。

我不明白为什么它是浅拷贝。 clone()将创建一个包含所有字段的新实例。 这只是一个很深的副本吗? 困惑。 需要一些解释。

默认的Object.clone()确实是浅拷贝。 但是,它被设计为抛出CloneNotSupportedException除非您的对象实现了Cloneable

当您实现Cloneable ,您应该通过在所有可复制的字段上调用clone()来覆盖clone()以使其执行深层复制。

顺便说一句,我很惊讶没有人提到Joshua Bloch对Cloneable的看法

如果您已经阅读了我的书中有关克隆的项目,特别是如果您在这些内容之间进行了阅读,您将会知道我认为克隆已经深受打击。 存在一些设计缺陷,其中最大的一个是Cloneable接口没有克隆方法。 这意味着它根本不起作用:制作一些Cloneable并没有说明你可以用它做什么。 相反,它说明了内部可以做些什么。 它说如果通过反复调用super.clone它最终调用Object的clone方法,这个方法将返回原始的字段副本。

clone()创建所有字段的副本。 Java具有原始类型和引用 – 当您克隆对象时,您将获得一个包含所有原始字段副本的新对象(就像深拷贝一样),但您也拥有所有引用字段的副本。 因此,在结果中,您将获得两个对象,它们拥有原始副本和对相同对象的引用副本 – 原始对象和复制对象都将使用相同的对象。

某些对象不提供深层副本。 例如,ArrayList将克隆列表,但不克隆列表中的元素。 以下是来自JavaDoc for ArrayList:

 public Object clone() Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.) 

它是浅拷贝,因为它只复制对其他对象的引用。 假设我们有这些课程:

 class A { B variable A() { variable = new B(); } } class B { } 

现在我们克隆一个A的实例:

 A firstA = new A(); A secondA = firstA.clone(); 

firstA和secondA中的B实例将是相同的。 您将没有B实例的副本。 这就是为什么说clone()做浅拷贝的原因。

您链接的页面上的图表应该可以帮助您理解所有这些。

为每个选择支持克隆的对象定义了什么克隆。 Object.clone受到保护,因此除非有人专门定义了对象,否则没有对象允许克隆。

Object.clone()的默认实现是浅表副本。 对于具有大量原始字段或不可变字段的类型,此行为仍然有用。 您可以查看如何正确覆盖克隆方法? 如何正确覆盖它。 在调用super.clone()之后,然后转换生成的对象,然后可以根据需要进行更深层次的克隆。

隐含地,随着类型上复杂的可变字段数量的增加,克隆的价值会减少。

是。

但首先你需要你的类将实现Cloneable并抛出exception

 class A implements Cloneable{ public int y; public B b; public A(){ b = new B(); } public static void main(String[] args) throws CloneNotSupportedException{ A a = new A(); A a2 = (A) a.clone(); System.out.print(ab==a2.b); } } 

输出:true