我正在阅读正确执行数组的深层拷贝,但是我对#clone()的实现感到困惑.它是
java.lang.Object类的成员,但如果您读取了javadocs:
First,if the class of this object does not implement the interface Cloneable,then a CloneNotSupportedException is thrown.
那么为什么要在那里定义克隆方法呢?当然如果一个方法只能在接口存在的时候使用,那么你可以将该方法放在接口中.可克隆的界面本身是空的它只是Java使用的标记界面,以确保使用克隆方法是合法的.
这样做也可以消除使用仿制药来确保类型安全的能力:
class Foo implements Cloneable { // Valid. @Override public Object clone() throws CloneNotSupportedException { // ... } } class TypeSafeFoo implements Cloneable<TypeSafeFoo> { // Not valid. @Override public TypeSafeFoo clone() throws CloneNotSupportedException { // ... } }
为什么Java这样做呢?我确定他们有合理的理由,但我似乎无法弄清楚.
解决方法
Java中的克隆合同规定每个克隆实现必须首先从super.clone()获取克隆的实例.这将创建一个永远以Object.clone调用结束的链,并且该方法包含“神奇”本机级代码,该代码构成了表示Java对象的底层原始结构体的二进制副本.如果此机制不存在,则克隆将不能是多态的:Object.clone方法会生成任何调用的类的实例;这不能没有本地代码复制.
这就是为什么不能避免Object.clone方法的原因.可克隆可能包含一个克隆方法,但它会产生关于throws子句的问题.它的方式可以自由地声明克隆,没有声明的例外,或声明任意异常.如果方法已经在接口中声明,那么这种灵活性是不可能的.
请记住,泛型对克隆没有什么用处:想象在对象中保护T克隆():T将来自哪里?我们需要Object< T>并强制Java Universe中的每一个类都可以自己进行参数化,这一切只是为了使这种半被淘汰的机制更好一些?还要记住,这段代码完全合法:
public class TheMightyOne implements Cloneable { @Override public TheMightyOne clone() { return (TheMightyOne) super.clone(); } }
你可以称之为:
TheMightyOne one = new TheMightyOne(); TheMightyOne two = one.clone(); // do downcasts needed