问题

众所周知,Java中的Cloneable接口被破坏了。这有很多原因,我不会提及; others已经做到了。它也是Java architects自己的立场。

因此,我的问题是:为什么还没有被弃用?如果核心Java团队已经确定它已被破坏,那么他们也必须考虑弃用。他们这样做的原因是什么(在Java 8中它是still not deprecated)?

#1 热门回答(117 赞)

在1997年提交的abug至Java Bug Database,并且在Cloneable中添加了clone()方法,因此它将不再是无用的。它以"不会修复"的决议结束,理由如下:

Sun的技术审查委员会(TRC)详细考虑了这个问题,并建议不要采取任何行动,而不是改进当前Cloneable接口的文档。以下是建议的全文:现有的Java对象克隆API存在问题。 java.lang.Object上有一个受保护的"clone"方法,并且有一个接口java.lang.Cloneable。目的是如果一个类想要允许其他人克隆它,那么它应该支持Cloneable接口并使用公共克隆方法覆盖默认的受保护克隆方法。不幸的是,由于在时间迷雾中方便丢失的原因,Cloneable接口没有定义克隆方法。这种组合导致了相当多的混乱。有些类声称支持Cloneable,但不小心忘记支持克隆方法。开发人员对Cloneable应该如何工作以及克隆应该做什么感到困惑。不幸的是,向Cloneable添加"克隆"方法将是一种不兼容的更改。它不会破坏二进制兼容性,但会破坏源兼容性。轶事证据表明,在实践中,有许多类支持Cloneable接口,但无法提供公共克隆方法。经过讨论,TRC一致建议我们不要修改现有的Cloneable接口,因为兼容性影响。另一个提议是添加一个新接口java.lang.PubliclyCloneable以反映Cloneable的原始预期目的。以5比2多数,TRC建议不要这样做。主要担心的是,这会给已经混乱的图片增加更多的混淆(包括拼写错误!)。 TRC一致建议我们应该在现有Cloneable接口上添加其他文档,以更好地描述它的使用方式,并为实现者描述"最佳实践"。

因此,虽然这不是直接关于不推荐的,但是不使Cloneable"弃用"的原因是,技术评审委员会决定修改现有文档的4669681446足以使这个界面变得有用了。所以他们做到了。直到Java 1.4,Cloneable记录如下:

一个类实现了Cloneable接口,以向Object.clone()方法指示该方法合法地为该类的实例创建一个field-for-field副本。尝试克隆未实现Cloneable接口的实例会导致抛出CloneNotSupportedException异常。 Cloneable接口声明没有方法。

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

一个类实现了Cloneable接口,以向Object.clone()方法指示该方法合法地为该类的实例创建一个field-for-field副本。在未实现Cloneable接口的实例上调用Object的clone方法会导致抛出异常CloneNotSupportedException。按照惯例,实现此接口的类应使用公共方法覆盖Object.clone(受保护)。有关重写此方法的详细信息,请参阅Object.clone()。请注意,此接口不包含克隆方法。因此,仅仅通过实现该接口的事实来克隆对象是不可能的。即使反射调用clone方法,也无法保证它会成功。

#2 热门回答(63 赞)

简单回答"为什么不是Cloneable贬低?" (或者实际上,为什么not1111428949已经过去,对于任何X而言)是因为对它们的弃用并没有太多关注。

最近弃用的大部分内容都已弃用,因为有一个特定的计划要删除它们。例如,addPropertyChangeListener和removePropertyChangeListener方法LogManagerwevedeprecated in Java SE 8,目的是在Java SE 9中删除它们。(原因是它们不必要地复杂了模块的相互依赖性。)实际上,这些API已经被开发了。 (请注意,类似的属性更改侦听器调用也从Pack200中删除;请参阅JDK-8029806。)

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

更长的答案将涉及讨论进一步的问题,例如人们可能期望在这些API上发生的事情,如果平台被弃用会产生什么样的成本或收益,以及在API被弃用时与开发人员沟通的内容。我在最近的JavaOne演讲Debt and Deprecation中探讨了这个主题。 (在该链接上可用的幻灯片; video here。)事实证明,JDK本身在使用弃用方面并不十分一致。它被用来表示几种不同的东西,包括例如,

这很危险,你应该知道使用它的风险(例如:Thread.stop(),Thread.resume()和Thread.suspend())。

这将在以后的版本中删除

这已经过时了,你最好使用不同的东西(例如:java.util.Date中的许多方法)

所有这些都是不同的含义,它们的不同子集适用于不推荐使用的不同内容。它们的一些子集适用于未弃用的东西(但可能应该弃用)。

Cloneable和Object.clone()在它们有设计缺陷并且难以正确使用的意义上是"破碎的"。但是,clone()仍然是复制数组的最佳方法,而克隆对于精心实现的类实例的副本有一些有限的用处。删除克隆将是一个不兼容的变化,会破坏很多东西。克隆操作可以以不同的方式重新实现,但它可能比Object.clone()慢。

但是,对于大多数情况,复制构造函数优于克隆。所以也许将Cloneable标记为"过时"或"被取代"或类似的东西是合适的。这将告诉开发人员他们可能想要寻找其他地方,但它不会表明在将来的版本中可能会删除克隆机制。不幸的是,不存在这样的标记。

事实上,"弃用"似乎意味着最终被删除 - 尽管事实上已经删除了少量被弃用的功能 - 因此克隆机制似乎不值得推荐。也许将来可以应用替代标记,指导开发人员使用替代机制。

更新

我已经为bug report添加了一些额外的历史记录。早期的JVM实现者和JVM规范的共同作者Frank Yellin在other answer引用的TRC建议中回应了"迷失在时间之中"的评论。我在这里引用了相关部分;完整的消息在错误报告中。

Cloneable没有方法与Serializable没有相同的原因。 Cloneable表示类的属性,而不是具体说明该类支持的方法。在反射之前,我们需要一个本机方法来制作一个Object的浅表副本。因此,Object.clone()诞生了。很明显,许多类都希望覆盖此方法,并且不是每个类都希望克隆。因此Cloneable的诞生是为了表明程序员的意图。所以,简而言之。 Cloneable的目的不是表明你有一个公共clone()方法。这表明你愿意使用Object.clone()进行克隆,并且由实现决定是否公开clone()。

#3 热门回答(-1 赞)

为什么它不被弃用了?

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

在Java API中保留此内容的原因是什么?

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

java cloneable 用途_为什么Cloneable不被弃用?相关推荐

  1. java cloneable 用途_java中cloneable的使用

    什么是java中的浅克隆和深克隆? 浅克隆:克隆对象中的变量与之前对象的值相同,并且对象中的引用类型变量仍然指向原来对象引用类型变量的地址. 深克隆:克隆对象中的变量与之前对象的值相同,并且对象中的引 ...

  2. java bitset用途_浅谈Java BitSet使用场景和代码示例

    搜索热词 @H_502_0@一.什么是BitSet? @H_502_0@ 注:以下内容来自JDK API: @H_502_0@ BitSet类实现了一个按需增长的位向量.位Set的每一个组件都有一个b ...

  3. java迭代器用途_各位JAVA前辈,迭代器使用报错。

    定义一个Student类, 类中封装了三个成员变量String name,int age,double score. 在测试类主方法中创建了几个Student类的对象,并添加到ArrrayList集合 ...

  4. JVM - 结合代码示例彻底搞懂Java内存区域_对象在堆-栈-方法区(元空间)之间的关系

    文章目录 Pre 示例demo 总体关系 代码示例论证 反汇编 Pre JVM - 结合代码示例彻底搞懂Java内存区域_线程栈 | 本地方法栈 | 程序计数器 中我们探讨了线程栈中的内部结构 ,大家 ...

  5. Java计算时间差_传统的SimpleDateFormat类

    Java计算时间差_传统的SimpleDateFormat类 SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd ...

  6. JAVA异常使用_每个人都曾用过、但未必都用得好

    JAVA异常使用_每个人都曾用过.但未必都用得好 一.抛出异常 vs. 返回错误代码 有人说"Well, an exception is a goto.",但也有人言"m ...

  7. 学习笔记:Java 并发编程①_基础知识入门

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 视频下载: ...

  8. Java应用编程_常用类库汇总2(日期类正则表达式国际化程序)

    总览[Java SE] 相关文章链接 [Java应用编程_常用类库汇总1(字符串处理类&&对象克隆&数字操作类库&-)] [Java应用编程_常用类库汇总3(开发支持类 ...

  9. ## 大一java课程设计_航班查询系统(我是小白)

    大一java课程设计_航班查询系统(我是小白) 备注:第一个java程序有借鉴别人的成分,因为忘了在哪个大佬上面借鉴的,所以在此备注,如有侵权,请联系删除,(仅用于学习使用,并未想盈利) 框体介绍 一 ...

最新文章

  1. 重新定位svn地址的方法(windows和linux),svn switch(sw)的帮助信息
  2. javascript写贪吃蛇
  3. 2015年百度一面试题
  4. Keras(part1)--Keras简介与安装
  5. PyQt中从RAM新建QIcon对象 / Create a QIcon from binary data
  6. G - 水陆距离 HihoCoder - 1478(广搜+队列先进先出性质)
  7. Virtools脚本语言(VSL)教程 - 枚举
  8. 高速通道-冗余物理专线接入-健康检查配置
  9. 读书笔记《Spring Boot实战 —— Java EE 开发的颠覆者》
  10. Linux 环境 简单启动 Java程序
  11. 通过日志分析mysql访问量,Mysql 慢查询和慢查询日志分析
  12. Word排版艺术 读后感
  13. matlab画图 横坐标为年月
  14. 超详细的Redis实战笔记
  15. HBase-2.0 MOB解决海量图片存储方案
  16. nas网络存储_网络附加存储NAS
  17. 简约黑板擦特效表白网源码
  18. git rebase详解(图解+最简单示例,一次就懂)
  19. 第三次作业:卷积神经网络基础
  20. 检测ip和port是否可连接

热门文章

  1. UnblockNeteaseMusic使用教程
  2. struts1中页面表单提交给action后页面一片空白,无错无异常
  3. php类型 fcgi,Apache使用fcgi方式与PHP结合
  4. Activate注解
  5. ASP.NET实例:用C#制作艺术字
  6. 812.最大三角形面积
  7. cognos安装教程linux,Cognos安装步骤Linux.doc
  8. 基于yolov5框架实现人流统计(目标检测算法、目标追踪算法以及越界识别功能)+手机获取统计人数
  9. js+css+html制作下拉菜单
  10. 2017年第5届东北亚 (沈阳)国际酒店用品展览会会刊(参展商名录)