24

我遇到了一些实现Clonable的类代码,文档指出:

一个类实现了 Cloneable 接口,以向 Object.clone() 方法指示该方法制作该类实例的逐个字段副本是合法的。在未实现 Cloneable 接口的实例上调用 Object 的 clone 方法会导致抛出异常 CloneNotSupportedException。按照惯例,实现此接口的类应使用公共方法覆盖 Object.clone(受保护的)。有关覆盖此方法的详细信息,请参阅 Object.clone()。请注意,此接口不包含 clone 方法。因此,不可能仅凭借实现该接口的事实来克隆对象。即使以反射方式调用 clone 方法,也不能保证它会成功。

我无法理解实现这个类的意义,正如文档中所说,该.clone方法没有在接口中实现,我必须实现它。那么为什么要使用这个类呢?为什么我不在我的copyClass类中编写一个方法来复制对象而不实现这个类?

4

3 回答 3

36

要实现克隆方法,您只需执行以下操作:

public Object clone() throws CloneNotSupportedException {
    return super.clone();
}

如果需要,您当然可以自定义该方法以制作更深的副本。

调用super.clone()几乎是强制性的,因为除非该类是最终类并且因此不能被覆盖,否则该clone()方法必须返回与调用它的对象相同的类的实例。因此,简单地创建一个新实例并复制状态将适用于此类,但不适用于所有子类。此外,您并不总是可以访问超类中包含的所有状态。

简而言之,您将 Object 的受保护克隆方法公开。该Object.clone()方法所做的第一件事是(这不是真正的代码,但这是该方法所做的):

if (!(this instanceof Cloneable)) {
    throw new CloneNotSupportedException();
}

所以,Cloneable只是一个标记接口,让Object.clone()方法知道它在调用时一定不能抛出异常。

这是 Java 设计最糟糕的部分之一。通常,您应该更喜欢使用复制构造函数而不是使用clone().

于 2013-05-12T13:10:48.903 回答
2

它允许您编写更通用的代码。如果您有多个实现Cloneable接口的类,并且想将它们的实例作为参数传递给方法,则不必创建多个与一种变量类型不同的方法,只需使用Cloneable t. 其他接口也一样。而且,与所有其他接口相同,它有点像多重继承。实现这些接口也使您的代码更加清晰。

于 2013-05-12T13:13:59.717 回答
0

除了别人说的,在实现原型设计模式的时候经常会用到Cloneable。

于 2019-05-26T04:41:13.827 回答