为什么#clone()不在Cloneable界面? [英] Why is #clone() not in the Cloneable interface?

查看:175
本文介绍了为什么#clone()不在Cloneable界面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读正确执行数组的深层拷贝,但是我对如何实现 #clone()感到困惑。它是 java.lang.Object 类的成员,但如果您阅读javadocs:

I was reading up on performing a deep-copy of an array correctly, however I was confused about how the #clone() is implemented. It is a member of the java.lang.Object class, and yet if you read the javadocs:


首先,如果此对象的类不实现Cloneable的接口,则抛出一个CloneNotSupportedException。

First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown.

那么为什么首先定义克隆方法呢?当然如果一个方法只能在接口存在的时候使用,你可以将该方法放在接口中。 Cloneable 界面本身是空的;它只是Java使用的标记界面,以确保使用克隆方法是合法的。

So why define the clone method there in the first place? Surely if a method can only be used when an interface is present, you'd put the method in the interface. The Cloneable interface itself is empty; it is just a marker interface used by Java to ensure that using the clone method is legal.

这样做方式也消除了使用泛型以确保类型安全的能力:

Doing it this way also removes the ability to make use of generics to ensure type safety:

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这样做?我确定他们有合法的理由,但我似乎无法弄清楚。

Why has Java done it this way? I'm sure they have legitimate reasons, but I can't seem to figure it out.

推荐答案

Java中的克隆合同规定每个克隆实现必须首先从 super.clone()获取克隆的实例。这将创建一个总是以调用 Object.clone 的方式结束的链接,该方法包含神奇本机级代码,它使基础原始 struct 表示Java对象。如果这种机制不存在, clone 将不能是多态的: Object.clone 方法生成一个无论什么类别都要求;这不能用本地代码复制。

The cloning contract in Java dictates that each clone implementation must first obtain the cloned instance from super.clone(). This creates a chain that always ends with the call to Object.clone, and that method contains "magical" native-level code that makes a binary copy of the underlying raw struct which represents the Java object. If this mechanism didn't exist, clone would fail to be polymorphic: the Object.clone method produces an instance of whatever class it is called on; this cannot be reproduced without native code.

这就是为什么不能避免 Object.clone 方法的原因。 可克隆 可以包含一个克隆方法,但会产生关于 throws 子句。它的方式可以自由地声明 clone ,没有声明的例外,或声明任意异常。如果该方法已经在界面中声明,那么这种灵活性是不可能的。

This is why the Object.clone method could not have been avoided. Cloneable could have contained a clone method, but it would create issues regarding the throws clause. The way it stands you are free to declare clone with no declared exceptions, or to declare arbitrary exceptions. This flexibility would not be possible if the method was already declared in the interface.

请记住,泛型将不会用于克隆:imagine Object 中保护T克隆(): T 来自哪里?我们需要 c> Object< T> 并强制 Java Universe 中的每个类都可以对其进行参数化,而且这只是为了使这个半被淘汰的机制工作好一点点?还要记住,这段代码是完全合法的:

Bear in mind that Generics would be of little use for cloning: imagine protected T clone() in Object: where would T come from? Would we need Object<T> and force each and every class in Java universe to be parameterized on itself, and all this just to make this semi-deprecated mechanism work a tiny bit better? Keep also in mind that this code is perfectly legal:

public class TheMightyOne implements Cloneable {
   @Override public TheMightyOne clone() {
     return (TheMightyOne) super.clone();
   }
}

您可以调用它:

TheMightyOne one = new TheMightyOne();
TheMightyOne two = one.clone(); // do downcasts needed

这篇关于为什么#clone()不在Cloneable界面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆