为什么java.lang.Cloneable不会覆盖java.lang.Object中的clone()方法?

Sup*_*tar 6 java clone cloneable

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

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

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

public static makeACloneFrom(Cloneable c)
{
  return c.clone();
}
Run Code Online (Sandbox Code Playgroud)

然而,情况并非如此,因为整个Cloneable源代码(sans javadoc)很简单

package java.lang;

public interface Cloneable {
}
Run Code Online (Sandbox Code Playgroud)

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

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

Lou*_*man 6

啊. clone并且Cloneable破碎,设计非常严格,不应在新代码中使用.(参见Effective Java第11项.)

这个特殊事物的原因是,这Cloneable是一个令人困惑的实现,神奇的界面,使得仅仅实施Cloneable的行为改变了Object.clone反射的行为.有效的Java说:

...如果一个类实现Cloneable,Objectclone方法返回对象的场逐场副本; 否则会抛出CloneNotSupportedException.这是一个非常非典型的接口使用,而不是一个被模仿的...


Mat*_*all 5

因为它是一个设计不佳的界面.

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

第11项:clone明智地改写

Cloneable接口旨在作为mixin接口(第18项),用于宣传他们允许克隆的对象.不幸的是,它没有达到这个目的.它的主要缺陷是,它缺乏一个 clone方法,和Objectclone方法是受保护的.借助于反射(第53项),你不能clone 仅仅因为它实现而在一个对象上调用该方法Cloneable.即使是反射调用也可能失败,因为无法保证对象具有可访问的clone方法.

  • 它应该在_long_之前改变了.但是,我认为它不会是因为它会引入向后兼容性.如果在Java 1.8中有一个"修复",我想它会像`@Cableable`注释一样. (2认同)
  • @SoboLAN你想改变它怎么样?删除它会导致许多兼容性问题,几乎没有收获.添加到设计糟糕的东西,你不应该使用,真的吗? (2认同)