为什么Java 8中的Cloneable中没有默认的clone() [英] Why no default clone() in Cloneable in Java 8

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

问题描述

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

Cloneable in Java is inherently broken. Specifically, my biggest problem with the interface is it expects a method behavior that doesn't define the method itself. So if traversing through a Cloneable list you must use reflection to access its defined behavior. However, in Java 8, we now have default methods and now I ask why there isn't a default clone() method in Cloneable.

我理解为什么接口不能默认使用Object方法,但是,这是一个明确的设计决策,因此可以进行异常。

I understand why interfaces cannot default Object methods, however, this was an explicit design decision and so exceptions can be made.

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

I sort of envision deprecating Object.clone() and changing its interior code to something like:

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

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

And moving on whatever magic makes clone() do its thing as a default method in Cloneable. This doesn't really fix that clone() can still easily be implemented incorrectly, but that's another discussion in of itself.

据我所知,此更改将完全向后兼容:

As far as I can still this change would be completely backwards compatible:


  1. 当前覆盖克隆的类()但没有实现 Cloneable (为什么?!)在技术上仍然没问题(即使功能上不可能,但这没有什么不同

  2. 当前覆盖 clone()的类,但确实实现了 Cloneable 在其实现上的功能仍然相同。

  3. 当前未覆盖的类 clone(),但是实现 Cloneable (为什么?!)现在将遵循规范,即使它不是完全在功能上正确。

  4. 使用反射并引用 Object.clone()的那些仍然可以正常工作。

  5. super.clone()在功能上仍然相同,即使它引用 Object.clone()

  1. Classes that currently override clone() but didn't implement Cloneable (WHY?!) would still be technically okay (even if functionally impossible, but this is no different then it was before).
  2. Classes that currently override clone(), but did implement Cloneable would still function the same on its implementation.
  3. Classes that don't currently override clone(), but did implement Cloneable (WHY?!) would now follow a specification, even if it's not completely functionally correct.
  4. Those that used reflection and referred to Object.clone() would still functionally work.
  5. super.clone() would still be functionally the same even if it's referencing Object.clone().

更不用说这将解决 Cloneable 的巨大问题。虽然繁琐但仍然很容易实现错误,但它可以解决界面的巨大面向对象问题。

Not to mention this would solve a huge problem that Cloneable is. While tedious and still easy to implement incorrectly, it would solve a huge object oriented problem with the interface.

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

The only problem I can see with this is those that implement Cloneable aren't obligated to override clone(), but this is no different than it was before.

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

Has this been discussed internally, but never came to fruition? If so, why? If it's for the reason that interfaces cannot default Object methods, wouldn't it make sense to make an exception in this case since all objects inheriting Cloneable are expecting clone() anyway?

推荐答案

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

Your question is somewhat broad and more of a discussion, but I can shed some light on this matter.

Effective Java™中,Joshua Bloch给出了相应的情况。他打开了 Cloneable

In Effective Java™, Joshua Bloch gives quite the rundown on the situation. He opens with a bit of history behind Cloneable


Cloneable接口的目标是对于
的对象的mixin接口宣传他们允许克隆。不幸的是,它没有达到这个目的。它的主要缺陷是缺少克隆方法,而Object的克隆方法受到保护。如果不依靠反射,就不能仅仅因为它实现Cloneable而对对象调用clone方法。

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]确定Object的受保护克隆实现的行为:如果类实现了Cloneable,则Object的clone方法返回逐个字段的副本对象...这是一个非常非典型的接口使用,而不是一个被模拟的接口。通常,实现接口会说明类可以为其客户做些什么。在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.


如果实现Cloneable接口对类有任何影响,
类及其所有超类必须服从相当复杂,不可执行的,并且
精简文件协议。结果机制是extralinguistic:它创建一个对象而不调用构造函数。

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.

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

There are a lot of details that go into this, but to note just one problem:


克隆体系结构与引用可变对象的最终字段的正常使用不兼容。

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

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

I think this is enough to reason against having a default method in the interface do the cloning. It would be extremely complicated to implement it correctly.

这篇关于为什么Java 8中的Cloneable中没有默认的clone()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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