clone()
在java中是浅拷贝吗?
最终这会到达 Object(最上层类)的 clone() 方法,该方法创建一个与对象相同的类的新实例,并将所有字段复制到新实例(“浅拷贝”)。
我从维基百科读到这个。
我不明白为什么它是浅拷贝。clone()
将创建一个包含所有字段的新实例。这只是一个深拷贝吗?使困惑。需要给我一些解释。
clone()
在java中是浅拷贝吗?
最终这会到达 Object(最上层类)的 clone() 方法,该方法创建一个与对象相同的类的新实例,并将所有字段复制到新实例(“浅拷贝”)。
我从维基百科读到这个。
我不明白为什么它是浅拷贝。clone()
将创建一个包含所有字段的新实例。这只是一个深拷贝吗?使困惑。需要给我一些解释。
默认Object.clone()
确实是浅拷贝。但是,它旨在抛出 a CloneNotSupportedException
,除非您的对象实现Cloneable
.
并且当您实现 时Cloneable
,您应该通过调用所有本身可克隆的字段来覆盖clone()
以使其进行深层复制。clone()
这是一个浅拷贝,因为它只复制对其他对象的引用。假设我们有这些类:
class A {
B variable
A() {
variable = new B();
}
}
class B { }
现在我们克隆 A 的一个实例:
A firstA = new A();
A secondA = firstA.clone();
firstA 和 secondA 中的 B 实例将是相同的。您将没有 B 实例的副本。这就是为什么说 clone() 做浅拷贝的原因。
您链接的页面上的图表应该可以帮助您理解所有这些。
顺便说一句,我很惊讶没有人提到Joshua Bloch 对 Cloneable 的看法
如果你读过我书中关于克隆的项目,尤其是如果你读到字里行间,你就会知道我认为克隆被严重破坏了。有一些设计缺陷,其中最大的一个是 Cloneable 接口没有克隆方法。这意味着它根本不起作用:制作可克隆的东西并没有说明你可以用它做什么。相反,它说明了它可以在内部做什么。它表示如果通过重复调用 super.clone 最终调用 Object 的 clone 方法,该方法将返回原始的字段副本。
clone() 创建所有字段的副本。Java 有原始类型和引用——当你克隆你的对象时,你会得到一个包含所有原始字段副本的新对象(它就像深拷贝),但你也有所有引用字段的副本。因此,结果你得到两个对象,它们拥有它们自己的原语副本和对相同对象的引用副本——原始对象和复制对象都将使用相同的对象。
有些对象不提供深拷贝。例如,ArrayList 将克隆列表,但不会克隆列表中的元素。以下来自 ArrayList 的JavaDoc:
public Object clone() Returns a shallow copy of this ArrayList instance. (The elements themselves are not copied.)
Object.clone() 的默认实现是浅拷贝。此行为对于具有大量原始字段或不可变字段的类型仍然有用。您可以查看如何正确覆盖克隆方法?如何正确覆盖它。在调用 super.clone(),然后转换生成的对象后,您可以根据需要进行更深的克隆。
隐含地,随着类型上复杂、可变字段数量的增加,clone 的值会减小。
clone
为选择支持克隆的每个对象定义了什么。Object.clone 是受保护的,因此除非有人明确定义,否则任何对象都不允许克隆。
是的。
但首先你需要你的类实现 Cloneable 并抛出异常
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(a.b==a2.b);
}
}
输出:真