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

Why do we implement Cloneable even if we can go for deep cloning using the following snippet

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;
}
}

在上面提到的 class ColoredCircle 中,我们有一个名为 testClone() 的方法,它的工作原理与深度克隆完全相同。 现在我对是否有必要实施 Cloneable 来克隆这一事实感到困惑? 上面的程序是不是深度克隆?

是否需要实施Cloneable克隆? Yes.The clone() 方法具有 受保护的访问修饰符 以及以下 Javadoc 说明:-

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

您的方法 testClone 虽然在克隆行为中可能是正确的,但在 itself.A 中不是可克隆对象 可克隆对象必须实现 Cloneable 接口并且最好具有 public clone() 的访问权限,以便它可以在 class.

之外使用

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

Cloneable 是一个标记接口。 它不包含任何方法。

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

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

注意: clone 方法也被标记为 protected。因此,重写它以使其 public 支持 classes 也是惯例。


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

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

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

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