java – 为什么#clone()不在Cloneable界面?

前端之家收集整理的这篇文章主要介绍了java – 为什么#clone()不在Cloneable界面?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_502_1@我正在阅读正确执行数组的深层拷贝,但是我对#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

猜你在找的Java相关文章