编程语言
首页 > 编程语言> > 为什么Java 8中的Cloneable中没有默认的clone()

为什么Java 8中的Cloneable中没有默认的clone()

作者:互联网

Java中的可克隆性本质上是破碎的.具体来说,我对界面的最大问题是它需要一种不定义方法本身的方法行为.因此,如果遍历Cloneable列表,则必须使用反射来访问其定义的行为.但是,在Java 8中,我们现在有了默认方法,现在我问为什么Cloneable中没有默认的clone()方法.

我理解为什么interfaces cannot default Object methods,这是一个明确的设计决定,因此可以做出例外.

我有点想象弃用Object.clone()并将其内部代码更改为:

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

继续使用任何魔法使clone()在Cloneable中作为默认方法.这并没有真正解决clone()仍然可以很容易地错误地实现,但这本身就是另一个讨论.

据我所知,这种变化将完全向后兼容:

>当前覆盖clone()但没有实现Cloneable(为什么?!)的类在技术上仍然可行(即使在功能上不可能,但这与以前没有什么不同).
>当前覆盖clone()但确实实现Cloneable的类在其实现上仍将起作用.
>当前没有覆盖clone()但是实现Cloneable(WHY ?!)的类现在将遵循规范,即使它在功能上并不完全正确.
>那些使用反射并引用Object.clone()的人仍然可以在功能上工作.
> super.clone()在功能上仍然是相同的,即使它引用了Object.clone().

更不用说这将解决Cloneable的一个巨大问题.虽然繁琐且仍然容易错误地实现,但它将解决界面的巨大面向对象问题.

我能看到的唯一问题是那些实现Cloneable的人没有义务覆盖clone(),但这与之前没有什么不同.

这已在内部进行过讨论,但从未取得成果吗?如果是这样,为什么?如果是因为接口不能默认使用Object方法,那么在这种情况下做出异常是否有意义,因为继承Cloneable的所有对象都期待clone()?

解决方法:

你的问题有点广泛而且更多的讨论,但我可以对这个问题有所了解.

在Effective Java™中,Joshua Bloch给出了相应的情况.他打开了Cloneable背后的一些历史

The Cloneable interface was intended as a mixin interface for objects to
advertise that they permit cloning. Unfortunately, it fails to serve this purpose. Its primary flaw is that it lacks a clone method, and Object’s clone method is protected. You cannot, without resorting to reflection, invoke the clone method on an object merely because it implements Cloneable.

并继续推理

[Cloneable] determines the behavior of Object’s protected clone implementation: if a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object… This is a highly atypical use of interfaces and not one to be emulated. Normally, implementing an interface says something about what a class can do for its clients. In the case of Cloneable, it modifies the behavior of a protected method on a superclass.

If implementing the Cloneable interface is to have any effect on a class, the
class and all of its superclasses must obey a fairly complex, unenforceable, and
thinly documented protocol. The resulting mechanism is extralinguistic: it creates an object without calling a constructor.

这里有很多细节,但要注意一个问题:

The clone architecture is incompatible with normal use of final fields referring to mutable objects.

我认为这足以说明在接口中使用默认方法进行克隆.正确实施它会非常复杂.

标签:default-method,cloneable,java,java-8,clone
来源: https://codeday.me/bug/20191005/1855845.html