5
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() 的方法,它的工作原理与深度克隆完全相同。现在我对是否有必要实现 Cloneable 来克隆这一事实感到困惑?上面的程序是一种深度克隆吗?

4

3 回答 3

3

Cloneable为了使调用Object.clone()不引发异常,需要实现接口。(这就是 . 的全部目的Cloneable。)

您没有使用Object.clone(). 所以执行Cloneable与否没有任何影响。它与您调用的方法无关。可以调用您的方法testClone(),并且最多可以调用super.clone(). 或者您的方法可以被调用clone(),但它不能使用super.clone(). 重要的是你没有使用Object.clone().

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

于 2015-10-17T09:01:53.010 回答
1

是否有必要Cloneable实施克隆?是的。clone() 方法具有受保护的访问修饰符,并带有以下 Javadoc 解释:-

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

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

阅读您的课程的人将很难理解testClone()方法的重要性。

于 2015-10-14T13:51:26.110 回答
0

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

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

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

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


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

于 2015-10-14T18:18:12.090 回答