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()方法?
啊. clone并且Cloneable破碎,设计非常严格,不应在新代码中使用.(参见Effective Java第11项.)
这个特殊事物的原因是,这Cloneable是一个令人困惑的实现,神奇的界面,使得仅仅实施Cloneable的行为改变了Object.clone反射的行为.有效的Java说:
...如果一个类实现
Cloneable,Object的clone方法返回对象的场逐场副本; 否则会抛出CloneNotSupportedException.这是一个非常非典型的接口使用,而不是一个被模仿的...
因为它是一个设计不佳的界面.
来自Effective Java(抱歉,Google Books没有第2版的预览版):
第11项:
clone明智地改写该
Cloneable接口旨在作为mixin接口(第18项),用于宣传他们允许克隆的对象.不幸的是,它没有达到这个目的.它的主要缺陷是,它缺乏一个clone方法,和Object的clone方法是受保护的.借助于反射(第53项),你不能clone仅仅因为它实现而在一个对象上调用该方法Cloneable.即使是反射调用也可能失败,因为无法保证对象具有可访问的clone方法.