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

前端之家收集整理的这篇文章主要介绍了java – 为什么#clone()不在Cloneable界面?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在阅读正确执行数组的深层拷贝,但是我对#clone()的实现感到困惑.它是 java.lang.Object类的成员,但如果您读取了javadocs:

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

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

这样做也可以消除使用仿制药来确保类型安全的能力:

  1. class Foo implements Cloneable { // Valid.
  2. @Override
  3. public Object clone() throws CloneNotSupportedException {
  4. // ...
  5. }
  6. }
  7.  
  8. class TypeSafeFoo implements Cloneable<TypeSafeFoo> { // Not valid.
  9. @Override
  10. public TypeSafeFoo clone() throws CloneNotSupportedException {
  11. // ...
  12. }
  13. }

为什么Java这样做呢?我确定他们有合理的理由,但我似乎无法弄清楚.

解决方法

Java中的克隆合同规定每个克隆实现必须首先从super.clone()获取克隆的实例.这将创建一个永远以Object.clone调用结束的链,并且该方法包含“神奇”本机级代码,该代码构成了表示Java对象的底层原始结构体的二进制副本.如果此机制不存在,则克隆将不能是多态的:Object.clone方法生成任何调用的类的实例;这不能没有本地代码复制.

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

请记住,泛型对克隆没有什么用处:想象在对象中保护T克隆():T将来自哪里?我们需要Object< T>并强制Java Universe中的每一个类都可以自己进行参数化,这一切只是为了使这种半被淘汰的机制更好一些?还要记住,这段代码完全合法:

  1. public class TheMightyOne implements Cloneable {
  2. @Override public TheMightyOne clone() {
  3. return (TheMightyOne) super.clone();
  4. }
  5. }

你可以称之为:

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

猜你在找的Java相关文章