为什么java.lang.Cloneable不重写java.lang.Object中的clone()方法?
为什么java.lang.Cloneable不重写java.lang.Object中的clone()方法?,java,clone,cloneable,Java,Clone,Cloneable,Java.lang.Cloneable接口的Java规范将自己定义为表示扩展它的任何对象也实现了在Java.lang.object中处于休眠状态的clone()方法。具体来说,它说: 类实现了Cloneable接口,以向java.lang.Object#clone()方法指示该方法为该类的实例创建字段对字段的副本是合法的 对我来说,这意味着应该假设每个扩展了Cloneable的类都有一个public Object clone()方法。这使得我们很容易假设以下方法是有效的: public stat
Java.lang.Cloneable
接口的Java规范将自己定义为表示扩展它的任何对象也实现了在Java.lang.object
中处于休眠状态的clone()
方法。具体来说,它说:
类实现了Cloneable
接口,以向java.lang.Object#clone()
方法指示该方法为该类的实例创建字段对字段的副本是合法的
对我来说,这意味着应该假设每个扩展了Cloneable
的类都有一个public Object clone()
方法。这使得我们很容易假设以下方法是有效的:
public static makeACloneFrom(Cloneable c)
{
return c.clone();
}
然而,情况并非如此,因为可克隆的源代码(sans-javadoc)的全部都是简单的
package java.lang;
public interface Cloneable {
}
这意味着Cloneable#clone()
不存在(尝试编译上面的示例方法会引发编译时错误,例如“找不到symbol:method clone()
”)。Cloneable
的源代码不应该包含类似于public Cloneable clone()的内容吗代码>
为什么不允许我们假设实现Cloneable
的类有一个公共Cloneable clone()
方法?,因为它是一个设计糟糕的接口
From(抱歉,Google Books没有第二版的预览版):
第11项:明智地覆盖克隆
Cloneable
接口旨在作为mixin接口(项目
18) 用于发布允许克隆的对象。不幸的是,
它没有达到这一目的。它的主要缺陷是缺少一个
clone
方法和对象的clone
方法受到保护。你
借助反射(第53项),无法调用克隆
方法仅因为它实现了可克隆性
。甚至是
反射调用可能会失败,因为无法保证
对象具有可访问的克隆方法
啊clone
和Cloneable
已损坏,设计糟糕,不应用于新代码中。(见有效Java第11项。)
之所以会出现这种特殊情况,是因为Cloneable
是一个令人困惑的、神奇的接口,仅仅实现Cloneable
的行为就可以通过反射改变对象的行为。有效的Java说:
…如果类实现了Cloneable
,Object
的clone
方法返回对象的逐字段副本;否则将抛出CloneNotSupportedException。这是一个非常非典型的接口使用,而不是一个被模仿
可能重复的。。。所以,在Java1.8中,这是一个应该改变的东西?它早就应该改变了。然而,我不认为它会是这样,因为它会引入向后的不兼容性。如果Java 1.8中有一个“修复”,我想它将是一个类似于@Copyable
注释的东西。@SoboLAN您希望它如何更改?删除它会导致很多兼容性问题,但收效甚微。加上一些设计糟糕、你不应该使用的东西,真的吗?::叹气::虽然我讨厌Cloneable
和clone
,但我宁愿看到它们被弃用,也不愿被彻底删除。尽管如此,Oracle不能完全重构所有Java用户的代码,它的政策是基本上避免不惜一切代价破坏外部代码。我不认为反射与之有任何关系(一方面它早于反射)。哦,天哪,那更邪恶。我猜clone
的本机实现相当于内部反射?根据Javadoc,“类对象的克隆方法执行特定的克隆操作。首先,如果这个对象的类没有实现接口Cloneable,那么就会抛出CloneNotSupportedException。请注意,所有数组都被视为实现接口可克隆,并且数组类型T[]的克隆方法的返回类型为T[],其中T是任何引用或基元类型。否则,此方法将创建此对象类的新实例,并使用此对象对应字段的内容初始化其所有字段。。。。。。仿佛通过转让;字段的内容本身不是克隆的。因此,此方法执行此对象的“浅拷贝”操作,而不是“深拷贝”操作。“是的,但它必须以本机方式而不是Java方式执行Cloneable
检查。