Java 让我的类实现Cloneable有什么意义?

Java 让我的类实现Cloneable有什么意义?,java,cloneable,Java,Cloneable,我遇到了一些实现Clonable的类代码,文档说明: 类实现可克隆接口以向Object.clone()方法指示该方法为该类的实例创建字段对字段副本是合法的。 在未实现可克隆接口的实例上调用对象的clone方法会引发异常CloneNotSupportedException。 按照约定,实现此接口的类应使用公共方法重写Object.clone(受保护)。有关重写此方法的详细信息,请参见Object.clone()。 请注意,此接口不包含克隆方法。因此,仅仅因为对象实现了该接口,就不可能克隆对象。即使

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

类实现可克隆接口以向Object.clone()方法指示该方法为该类的实例创建字段对字段副本是合法的。 在未实现可克隆接口的实例上调用对象的clone方法会引发异常CloneNotSupportedException。 按照约定,实现此接口的类应使用公共方法重写Object.clone(受保护)。有关重写此方法的详细信息,请参见Object.clone()。 请注意,此接口不包含克隆方法。因此,仅仅因为对象实现了该接口,就不可能克隆对象。即使以反射方式调用clone方法,也不能保证它会成功


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

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

public Object clone() throws CloneNotSupportedException {
    return super.clone();
}
当然,如果需要,您可以自定义该方法以制作更深入的副本

调用
super.clone()。因此,简单地创建一个新实例并复制状态将适用于该类,但不适用于所有子类。此外,您并不总是能够访问超类中包含的所有状态

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

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


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

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

除了其他人所说的,在实现原型设计模式时通常使用Cloneable。

您让类实现Cloneable,以便您可以使用内置的克隆机制,因此,其他类可以克隆您的类,而不必知道它的唯一克隆方法。是的,这是一种有点奇怪的管理方式,但部分原因与向后兼容性有关。从您的回答中我可以理解,今天不建议使用此接口,它的唯一用途是:如果我想使用Object class的clone方法,那么我应该实现它。在我的例子(我看到此实现的类)中,实现了该类的更深层副本,因此在本例中,实现此接口的原因是什么?如果要重写并使用
Object.clone()
方法,则需要实现此接口。如果你想以另一种方式执行复制,那就做你想做的。明白了,所以重写Object.clone()会迫使我使用这个接口。感谢您提供了丰富的答案。>通常,您应该更喜欢使用复制构造函数,而不是使用clone()。复制构造函数的问题,正如我最后发现的,是当您必须复制只知道接口类型的对象时,它们是一个错误的选择。例如,如果您有一个对象A,其中包含一个列表,其中的对象是一个接口,那么您就被搞砸了,因为您不知道列表中的对象的确切类型,因此在这种情况下,您不能使用复制构造函数克隆列表中的对象。
if (!(this instanceof Cloneable)) {
    throw new CloneNotSupportedException();
}