Cloneable
Java 本质上是破碎的。具体来说,我对接口的最大问题是它需要一种不定义方法本身的方法行为。所以如果遍历一个Cloneable
列表中您必须使用反射来访问其定义的行为。然而,在 Java 8 中,我们现在有了默认方法,现在我问为什么没有默认方法clone()
中的方法Cloneable
.
我明白为什么接口不能默认对象方法然而,这是一个明确的设计决定,因此可以有例外。
我有点想弃用Object.clone()
并将其内部代码更改为:
if(this instanceof Cloneable) {
return ((Cloneable) this).clone();
}
else {
throw new CloneNotSupportedException();
}
继续前进,无论魔法如何clone()
作为默认方法做它的事情Cloneable
。这并不能真正解决这个问题clone()
仍然很容易被错误地实现,但这本身就是另一个讨论。
据我所知,此更改将完全向后兼容:
- 当前覆盖的类
clone()
但没有实施Cloneable
(为什么?!)在技术上仍然可以(即使在功能上不可能,但这与以前没有什么不同)。
- 当前覆盖的类
clone()
,但确实实施了Cloneable
在其实施中仍将发挥相同的作用。
- 当前不覆盖的类
clone()
,但确实实施了Cloneable
(为什么?!)现在会遵循规范,即使它不是完全地功能上正确。
- 那些使用反射并引用的
Object.clone()
仍然可以正常工作。
-
super.clone()
即使它引用了,功能上仍然是相同的Object.clone()
.
更不用说这将解决一个巨大的问题Cloneable
是。虽然乏味并且仍然很容易错误地实现,但它可以解决接口的一个巨大的面向对象问题。
我能看到的唯一问题是那些实施Cloneable
没有义务覆盖clone()
,但这和以前没有什么不同。
内部是否讨论过,但从未实现?如果是这样,为什么?如果是因为接口不能默认对象方法,那么在这种情况下抛出异常是否有意义,因为所有对象都继承Cloneable
正在期待clone()
anyway?
你的问题有点宽泛,更多的是讨论,但我可以对这个问题做出一些说明。
In 有效的Java™约书亚·布洛赫 (Joshua Bloch) 对这种情况做了相当的概述。他以一些背后的历史开场Cloneable
Cloneable 接口旨在作为对象的 mixin 接口
宣传他们允许克隆。不幸的是,它未能达到这个目的。它的主要缺陷是缺少clone方法,而Object的clone方法是受保护的。如果不借助反射,您不能仅仅因为对象实现了 Cloneable 就调用该对象的克隆方法。
并继续推理
[Cloneable] 决定了 Object 的受保护克隆实现的行为:如果一个类实现了 Cloneable,则 Object 的克隆方法将返回该对象的逐字段副本...这是一种非常非典型的接口使用,而不是可以模拟的。通常,实现一个接口说明了一个类可以为其客户做什么。对于 Cloneable,它修改超类上受保护方法的行为。
and
如果实现 Cloneable 接口是为了对类产生任何影响,则
类及其所有超类必须遵守相当复杂的、不可执行的且
记录很少的协议。由此产生的机制是语言外的:它创建一个对象而不调用构造函数。
这涉及到很多细节,但要注意一个问题:
克隆架构与引用可变对象的最终字段的正常使用不兼容。
我认为这足以成为反对的理由default
接口中的方法进行克隆。正确实施它会非常复杂。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)