在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