Java中的Cloneable本质上是损坏的。具体来说,我与接口(interface)的最大问题是它期望方法行为无法定义方法本身。因此,如果遍历Cloneable列表,则必须使用反射来访问其定义的行为。但是,在Java 8中,我们现在有了默认方法,现在我问为什么clone()中没有默认的Cloneable方法。

我理解interfaces cannot default Object methods的原因,但是,这是一个明确的设计决定,因此可以进行异常(exception)处理。

我有点设想弃用Object.clone()并将其内部代码更改为类似以下内容:

if(this instanceof Cloneable) {
    return ((Cloneable) this).clone();
}
else {
    throw new CloneNotSupportedException();
}

并继续前进,使clone()作为Cloneable中的默认方法完成其工作的任何魔术。这并不能真正解决clone()仍然很容易被错误地实现的问题,但这本身就是另外一个讨论。

据我所知,此更改将完全向后兼容:
  • 当前覆盖clone()但未实现Cloneable(WHY ?!)的类在技术上还是可以的(即使在功能上是不可能的,但这和以前没什么不同)。
  • 当前覆盖clone(),但实现了Cloneable的类在其实现上仍具有相同的功能。
  • 当前未覆盖clone(),但确实实现了Cloneable(WHY ?!)的类现在将遵循规范,即使它在功能上并不完全正确。
  • 那些使用反射并引用了Object.clone()的程序仍然可以正常工作。
  • super.clone()即使在引用Object.clone()时在功能上也相同。

  • 更不用说这将解决Cloneable是一个巨大的问题。尽管繁琐并且仍然容易错误地实现,但是它将解决接口(interface)的一个巨大的面向对象的问题。

    我唯一可以看到的问题是那些实现Cloneable的对象没有义务重写clone(),但这与以前没有什么不同。

    是否在内部进行过讨论,但从未实现过?如果是这样,为什么?如果是由于接口(interface)无法默认Object方法的原因,那么在这种情况下将异常设置为有意义,因为所有继承Cloneable的对象仍然期望clone()吗?

    最佳答案

    您的问题有些广泛,需要更多讨论,但我可以就此问题提供一些启示。

    在“有效的Java™”中,Joshua Bloch给出了有关情况的简要说明。他以Cloneable背后的历史开始



    并继续推理







    这涉及很多细节,但仅需注意一个问题:



    我认为这足以使我们反对在接口(interface)中使用default方法进行克隆。正确实现它将极其复杂。

    10-05 18:27