Java 为什么Cloneable没有被弃用?

Java 为什么Cloneable没有被弃用?,java,java-8,deprecated,cloneable,Java,Java 8,Deprecated,Cloneable,人们普遍认为Java中的Cloneable接口已损坏。原因很多,我不说,;已经做了。这也是他们自己的立场 因此,我的问题是:为什么还没有被否决?如果核心Java团队认为它已被破坏,那么他们一定也考虑过弃用。他们反对这样做的理由是什么(在Java8中就是这样) 为什么它还没有被弃用 因为JCP认为这样做不合适,而且可能永远不会这样做。问问他们。你问错地方了 将这个东西保留在JavaAPI中的原因是什么 由于向后兼容性的要求,没有人会从JavaAPI中删除任何内容。上一次发生的是1996/7年AWT

人们普遍认为Java中的
Cloneable
接口已损坏。原因很多,我不说,;已经做了。这也是他们自己的立场

因此,我的问题是:为什么还没有被否决?如果核心Java团队认为它已被破坏,那么他们一定也考虑过弃用。他们反对这样做的理由是什么(在Java8中就是这样)

为什么它还没有被弃用

因为JCP认为这样做不合适,而且可能永远不会这样做。问问他们。你问错地方了

将这个东西保留在JavaAPI中的原因是什么

由于向后兼容性的要求,没有人会从JavaAPI中删除任何内容。上一次发生的是1996/7年AWT事件模型在1.0和1.1之间的变化。

1997年提交了一份关于将
clone()
方法添加到
Cloneable
,因此它不再是无用的。决议以“不会修复”结束,理由如下:

Sun的技术审查委员会(TRC)详细考虑了这个问题 并建议不要采取除改善 当前可克隆接口的文档。这是全文 建议案文:

现有的Java对象克隆API存在问题。有一个 受保护的java.lang.Object上的“clone”方法,并且有一个接口 java.lang.Cloneable。其目的是,如果一个类想要允许 其他人克隆它,那么它应该支持克隆 接口并使用 公共克隆方法。不幸的是,由于某些原因,我们很容易迷失了方向 在时间的迷雾中,可克隆接口没有定义克隆 方法

这种组合会导致相当多的混乱。一些班级 声称支持Cloneable,但意外忘记支持 克隆方法。开发人员对可克隆性的概念感到困惑 以及克隆人应该做什么

不幸的是,将“克隆”方法添加到Cloneable将是一个错误 不相容的变化。它不会破坏二进制兼容性,但会 中断源代码兼容性。传闻证据表明,在 实践中有很多情况下,类支持 可克隆接口,但无法提供公共克隆方法。之后 经过讨论,真相与和解委员会一致建议,我们不应修改 由于兼容性影响,现有可克隆接口

另一个建议是添加一个新接口 java.lang.PubliclyClonable可反映最初的预期用途 可克隆的。真相与和解委员会以5比2的多数反对这一点。 主要担心的是,这会增加更多的混乱(包括 拼写混乱!)到已经混乱的图片

真相与和解委员会一致建议我们增加额外的 现有可克隆接口的文档,以便更好地描述 计划如何使用,以及如何描述“最佳实践” 实施者

因此,尽管这并不是直接与弃用有关,但不使可克隆“弃用”的原因是,技术评审委员会决定,修改现有文档将足以使此界面变得有用。他们就这样做了。在Java 1.4之前,
Cloneable
的文档记录如下:

类实现可克隆接口以向 Object.clone()方法,该方法创建 该类实例的逐字段副本

尝试克隆未实现可克隆性的实例 接口导致异常CloneNotSupportedException为 扔

接口Cloneable未声明任何方法

从Java 1.4(于2002年2月发布)到当前版本(Java 8),它看起来是这样的:

类实现可克隆接口以向 Object.clone()方法,该方法创建 该类实例的逐字段副本。调用对象的 在未实现可克隆性的实例上克隆方法 接口导致异常CloneNotSupportedException被删除 扔

按照约定,实现此接口的类应该重写 Object.clone(受保护)使用公共方法。看见 有关重写此方法的详细信息,请参阅Object.clone()

请注意,此接口不包含克隆方法。所以,, 仅仅凭借事实是不可能克隆一个物体的 它实现了这个接口。即使调用了clone方法 反省一下,这并不能保证它会成功

对于“为什么
Cloneable
不推荐使用?”(或者实际上,对于任何
X
,为什么
X
不推荐使用)的简短回答是,没有太多人注意不推荐它们

最近被弃用的大多数东西都被弃用了,因为有一个特定的计划来删除它们。例如,的
addPropertyChangeListener
removePropertyChangeListener
方法旨在在JavaSE9中删除它们。(原因是它们不必要地使模块相互依赖性复杂化。)事实上,这些API已经被开发构建。(请注意,类似的属性更改侦听器调用也已从
Pack200
中删除;请参阅。)

对于
Cloneable
Object.clone()
,没有类似的计划

一个较长的答案将涉及到讨论更多的问题,例如人们可能期望这些API会发生什么,如果它们被弃用,平台将产生什么成本或收益,以及将向开发人员传达什么