为什么即使我们可以使用以下代码段进行深度克隆,我们也会实现Cloneable

时间:2015-10-14 13:32:58

标签: java interface clone cloning cloneable

public class Color {
 String color;
 Color(String color)
 {
   this.color=color;         
 }
 }


public class ColoredCircle {
int x;
Color color;
ColoredCircle(int x, Color color)
{
    this.x=x;
    this.color=color;
}
public Object testClone()
{
    Color c = new Color(this.color.color);
    ColoredCircle cc1 = new ColoredCircle(this.x, c);
    return cc1;
}
}

在上面提到的ColoredCircle类中,我们有一个名为testClone()的方法,它与Deep Cloning完全相同。 现在我很困惑,有必要实现Cloneable克隆吗? 以上程序是一种深度克隆吗?

3 个答案:

答案 0 :(得分:2)

需要实现Cloneable接口才能调用Object.clone()不抛出异常。 (这是Cloneable的全部目的。)

您没有使用Object.clone()。因此,实施Cloneable与否是没有效果的。它与您的方法调用无关。您的方法可以调用testClone(),最多可以调用super.clone()。或者您的方法可能被称为clone(),并且无法使用super.clone()。重要的是你没有使用Object.clone()

使用Object.clone()的优点是它返回的对象与调用它的对象具有完全相同的运行时类。另一方面,您的方法始终创建一个新的ColoredCircle对象。因此,当您的testClone()方法在子类中继承时,它仍将创建ColoredCircle,而不是该子类的实例。如果您的方法调用super.clone(),它将能够获取当前实例的任何子类的实例。

答案 1 :(得分:1)

是否有必要将Cloneable实施为克隆?是.clone()方法具有受保护的访问修饰符,其中包含以下Javadoc说明: -

此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样;这些字段的内容本身不会被克隆。因此,此方法执行此对象的shallow copy,而不是deep copy操作。

您的方法testClone虽然在克隆行为中可能是正确的,但本身不是可克隆对象。可克隆对象必须实现Cloneable接口,并且最好具有clone()的公共访问权限它可以在课外使用。

有人在课堂上重读testClone()方法的重要性。

答案 2 :(得分:0)

Cloneable是一个标记界面。它不包含任何方法。

问题是clone类中定义了Object方法。由于所有类都实现了Object类,这意味着所有类都有clone方法。但是,并非所有对象都支持它。他们中的一些人只会抛出一个CloneNotSupportedException。但是这个克隆方法是一个native方法,因此这个方法的确切行为在java源代码中是不可见的。所以,它缺乏透明度。

Cloneable界面可以帮助我们识别哪些类是可克隆的,哪些不是。按照惯例,未实现Cloneable的类将抛出CloneNotSupportedException

注意: clone方法也标记为protected。因此,覆盖它以使其在支持类中成为public也是惯例。

JDK1中引入了clone设计。这些天普遍的共识是java clone设计包含一些缺陷。有些人更喜欢创建一个克隆构造函数(例如public Color(Color toCopy) {this.color = toCopy.color;}