9

接口的 Java 规范java.lang.Cloneable将其自身定义为表示扩展它的任何对象也实现了clone()java.lang.Object. 具体来说,它说:

一个类实现该Cloneable接口以向该java.lang.Object#clone()方法指示该方法制作该类实例的逐个字段副本是合法的。

对我来说,这意味着应该假设每个扩展的类Cloneable因此也有一个public Object clone()方法。这使得很容易假设以下是一个有效的方法:

public static makeACloneFrom(Cloneable c)
{
  return c.clone();
}

然而,情况并非如此,因为整个Cloneable源代码(无 javadoc)只是

package java.lang;

public interface Cloneable {
}

这意味着它Cloneable#clone()不存在(并且尝试编译上面的示例方法会引发编译时错误,例如“ cannot find symbol: method clone()”)。源代码不应该Cloneable包含一些效果public Cloneable clone();吗?

为什么我们不允许假设实现的类Cloneablepublic Cloneable clone()方法?

4

2 回答 2

7

因为它是一个设计糟糕的界面。

来自Effective Java(抱歉,Google Books 没有第 2 版的预览):

clone第 11 项:明智地覆盖

The Cloneable interface was intended as a mixin interface (Item 18) for objects to advertise that they permit cloning. Unfortunately, it fails to serve this purpose. Its primary flaw is that it lacks a clone method, and Object's clone method is protected. You cannot, with resorting to reflection (Item 53), invoke the clone method on an object merely because it implements Cloneable. Even a reflective invocation may fail, as there is no guarantee that the object has an accessible clone method.

于 2012-04-02T18:31:31.890 回答
7

Ugh. clone and Cloneable are broken, terribly designed, and shouldn't be used in new code. (See Effective Java item 11.)

The reason for this particular thing is that Cloneable is a confusingly implemented, magical interface such that the mere act of implementing Cloneable changes the behavior of Object.clone with reflection. Effective Java says:

...if a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException. This is a highly atypical use of interfaces and not one to be emulated...

于 2012-04-02T18:33:05.507 回答