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

2023-11-25

CloneableJava 本质上是破碎的。具体来说,我对接口的最大问题是它需要一种不定义方法本身的方法行为。所以如果遍历一个Cloneable列表中您必须使用反射来访问其定义的行为。然而,在 Java 8 中,我们现在有了默认方法,现在我问为什么没有默认方法clone()中的方法Cloneable.

我明白为什么接口不能默认对象方法然而,这是一个明确的设计决定,因此可以有例外。

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

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

继续前进,无论魔法如何clone()作为默认方法做它的事情Cloneable。这并不能真正解决这个问题clone()仍然很容易被错误地实现,但这本身就是另一个讨论。

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

  1. 当前覆盖的类clone()但没有实施Cloneable(为什么?!)在技术上仍然可以(即使在功能上不可能,但这与以前没有什么不同)。
  2. 当前覆盖的类clone(),但确实实施了Cloneable在其实施中仍将发挥相同的作用。
  3. 当前不覆盖的类clone(),但确实实施了Cloneable(为什么?!)现在会遵循规范,即使它不是完全地功能上正确。
  4. 那些使用反射并引用的Object.clone()仍然可以正常工作。
  5. 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(使用前将#替换为@)

为什么 Java 8 中的 Cloneable 没有默认的 clone() 的相关文章

  • 具有更高可见性的重写方法是良好的实践吗?

    回答这个问题 如何使用 GUI 使用 PaintComponent 初始化 GUI 然后添加基于鼠标的 GUI https stackoverflow com questions 21336141 how to gui using pain
  • 清理码头 - 删除“不必要”的东西

    我习惯用Jetty http jetty codehaus org jetty 作为我的网络容器 我对我做了什么安装步骤得到原始的焦油球并且清理一些目录和文件从中 我在这里想提出的是 您通常从 Jetty 中删除什么以在生产 登台环境中使用
  • Android 2.2 SDK - Droid X 相机活动无法正常完成

    我注意到我在 Droid X 上调用的默认相机活动与我的 Droid 和 Nexus One 上的默认相机活动看起来不同 在 Droid 和 Nexus One 上选择 确定 后 活动将完成 Droid X 有一个 完成 按钮 它将带您返回
  • 无法使用maven编译java项目

    我正在尝试在 java 16 0 1 上使用 maven 构建 IntelliJ 项目 但它无法编译我的项目 尽管 IntelliJ 能够成功完成 在此之前 我使用maven编译了一个java 15项目 但我决定将所有内容更新到16 0 1
  • 如何从秘密字符串中制作 HMAC_SHA256 密钥以在 jose4j 中与 JWT 一起使用?

    我想生成 JWT 并使用 HMAC SHA256 对其进行签名 对于该任务我必须使用jose4j https bitbucket org b c jose4j wiki Home 我尝试根据秘密生成密钥 SecretKeySpec key
  • Spring安全“记住我”cookie在第一个请求中不可用

    我无法在登录请求后检索 Spring 记住我 cookie 但它在对受保护页面的下一个请求中工作正常 谁能告诉我怎样才能立即得到它 我在登录请求中设置了记住我的 cookie 但在 Spring 重定向回原始 受保护的 url 后无法检索它
  • 在文本文件中搜索单词并返回其频率

    如何在包含单词文本的文本文件中搜索特定单词并返回其频率或出现次数 使用扫描仪 String text Question how to search for a particular word in a text file containin
  • 使用 RecyclerView 适配器在运行时更改布局屏幕

    我有两个布局文件 如下所示 如果列表中存在数据 则我显示此布局 当列表为空时 我会显示此布局 现在我想在运行时更改布局 当用户从列表中删除最后一项时 我想将布局更改为第二张图片中显示的 空购物车布局 In getItemCount Recy
  • 主线程如何在该线程之前运行?

    我有以下代码 public class Derived implements Runnable private int num public synchronized void setA int num try Thread sleep 1
  • 如何从 Retrofit2 获取字符串响应?

    我正在做 android 正在寻找一种方法来执行超级基本的 http GET POST 请求 我不断收到错误 java lang IllegalArgumentException Unable to create converter for
  • 如何将 android.net.Uri 转换为 java.net.URL? [复制]

    这个问题在这里已经有答案了 有没有办法从Uri to URL 我正在使用的库需要这个 它only接受一个URL但我需要在我的设备上使用图像 如果该方案的Uri is http or https new URL uri toString 应该
  • Java:正则表达式排除空值

    在问题中here https stackoverflow com questions 51359056 java regexp for a separated group of digits 我得到了正则表达式来匹配 1 到 99 之间的一
  • Java 数组的最大维数

    出于好奇 在 Java 中数组可以有多少维 爪哇language不限制维数 但是JavaVM规范将维度数限制为 255 例如 以下代码将无法编译 class Main public static void main String args
  • 计算日期之间的天数差异

    在我的代码中 日期之间的差异是错误的 因为它应该是 38 天而不是 8 天 我该如何修复 package random04diferencadata import java text ParseException import java t
  • Dispatcher-servlet 无法映射到 websocket 请求

    我正在开发一个以Spring为主要框架的Java web应用程序 特别使用Spring core Spring mvc Spring security Spring data Spring websocket 像这样在 Spring 上下文
  • 如何通过 Inno Setup for NetBeans 使用自定义 .iss 文件

    我将 Inno Setup 5 与 NetBeans 8 一起使用 并且我已经能够创建一个安装程序来安装该应用程序C users username local appname 但是我希望将其安装在C Programfiles 我如何在 Ne
  • 如何在Java中正确删除数组[重复]

    这个问题在这里已经有答案了 我刚接触 Java 4 天 从我搜索过的教程来看 讲师们花费了大量精力来解释如何分配二维数组 例如 如下所示 Foo fooArray new Foo 2 3 但我还没有找到任何解释如何删除它们的信息 从内存的情
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht
  • Java &= 运算符应用 & 或 && 吗?

    Assuming boolean a false 我想知道是否这样做 a b 相当于 a a b logical AND a is false hence b is not evaluated 或者另一方面 这意味着 a a b Bitwi
  • Android 和 Java 中绘制椭圆的区别

    在Java中由于某种原因Ellipse2D Double使用参数 height width x y 当我创建一个RectF在Android中参数是 left top right bottom 所以我对适应差异有点困惑 如果在 Java 中创

随机推荐

  • 为什么 document.getElementsBy__ 方法不返回 HTMLCollection?

    为什么不getElementsByName getElementsByTagName and getElementsByClassName返回一个HTMLCollection W3C MDN 代替NodeList W3C MDN 所有这三个
  • 什么是 org.eclipse.wst.common.component 以及如何将它用于 ant

    我有一个 Eclipse 工作区 用于工作 其中有一个 Ear 项目 我用它来 导出 将 Ear 文件部署到 JBoss 服务器 然而 他们最近要求我创建一个可以构建工作区并创建耳朵的 Ant 脚本 我已经成功地完成了这一点 当我尝试使用使
  • 带有Rails ajax的pushState

    我有一个索引操作页面 显示了用 Kaminari 分页的项目列表 我已经向它们添加了 ajax 功能 现在正在尝试使用 PushState 来获取适合的 URL 我的问题是 当我的分页链接通过以下方式完成时 如何获取传递给 PushStat
  • Gson 可选字段和必填字段

    一个人应该如何应对Gson必填字段与可选字段 由于所有字段都是可选的 因此我无法根据响应 json 是否包含某个键来真正使我的网络请求失败 Gson将简单地将其解析为 null 我正在使用的方法gson fromJson json mCla
  • 增加具有不同线程数的 2 个交替 OpenMP 并行区域的内存消耗

    当我重复在具有不同线程数的 2 个 OpenMP 并行区域之间交替时 内存消耗无限增加 数十 MB 甚至更多 即使在如此简单的代码片段中它也能做到这一点 include
  • 轮盘赌选择算法[重复]

    这个问题在这里已经有答案了 谁能提供一些轮盘赌选择函数的伪代码 我将如何实现这个 我真的不明白如何阅读这个数学符号 我想要通用算法 其他答案似乎假设您正在尝试实现轮盘赌游戏 我认为您问的是进化算法中的轮盘赌选择 这是一些Java代码实现轮盘
  • 如何在 Elixir 中重写 Erlang 组合算法?

    过去几周我一直在修补 Elixir 我刚刚遇到这个简洁的Erlang 中的组合算法 我尝试在 Elixir 中重写但卡住了 艾尔兰版本 comb 0 gt comb gt comb N H T gt H L L lt comb N 1 T
  • 在 Android 应用程序中显示日历

    如果有人能为我提供一个关于使用哪个组件的解决方案 以便我可以在我的 Android 应用程序中显示一个相当漂亮的日历 我将不胜感激 这两天我一直在寻找解决方案 但不幸的是找不到解决方案 由于这是一个非常基本的要求 我相信会有一个完美的解决方
  • C/C++ 编译器可以通过 pthread 库调用合法地将变量缓存在寄存器中吗?

    假设我们有以下代码 include
  • 为 PL/pgSQL 中实现的函数设置配置参数

    我在 PL pgSQL 中编写了几个函数 我想通过一些配置条目来控制它们的行为 这些配置条目也可以在运行时更改 每个会话 是否可以在中定义新的自定义配置条目postgresql conf 如果没有 解决办法是什么 作为我的搜索结果 我发现了
  • Python 多重处理 >= 125 列表永远不会完成

    我正在尝试实现这个多处理tutorial为了我自己的目的 起初我认为它的扩展性不好 但是当我做了一个可重现的示例时 我发现如果项目列表超过 124 它似乎永远不会返回答案 在x 124它在 0 4 秒内运行 但是当我将其设置为x 125它永
  • Python简单的音频生成器

    寻找一些 简单的 Python 音调生成器 用于在带有 USB 声卡的 raspi 上运行的以下脚本 需要动态音调开 关和频率改变 import serial time ser serial Serial dev ttyUSB0 9600
  • 使用 ggplot2 将 x 轴和 y 轴居中

    有没有办法像传统的图形计算器一样获取坐标轴 并将标签放在 ggplot2 图的中心 我浏览了文档 似乎没有这个功能 但其他绘图包不像 ggplot2 那样可以进行图形定制 为了澄清一下 我希望从这样的事情开始 To this 第一个图是用以
  • 如何在ios中获取twitter个人资料图片?

    我写了以下代码 NSURL url NSURL URLWithString http api twitter com 1 1 users show json NSDictionary params NSDictionary dictiona
  • ComboBox 下拉时如何捕获鼠标?

    我正在尝试对 ComboBox 下拉菜单 或与此相关的其他下拉菜单 包括上下文菜单 的行为进行建模 其中当您单击其他任何位置 甚至无法聚焦的内容 时 下拉菜单会关闭 我尝试过订阅 MouseCaptureChanged LostFocus
  • sed 替换部分字符串

    我想使用 sed 执行以下操作 case 1 here is some random text constant randomValue some more random text 我想在constant 之后直接替换randomvalue
  • 尝试从内部 Zip 文件(另一个 Zip 中的 Zip)获取流时出现“无法将其读取为 Zip 文件”异常

    在 C 中 我使用的是点网压缩我有一个名为 innerZip zip 的 zip 其中包含一些数据 另一个名为 outerZip zip 的 zip 包含了 innerZip 我为什么要这样做 好吧 在设置密码时 密码实际上适用于添加到存档
  • 使用 ArtistAnimation 在 matplotlib 中对 png 进行动画处理

    我一直在尝试使用有限元方法为二维热流问题创建一系列曲面图的动画 在每个时间步 我保存一个图而不是整个矩阵 以便更加高效 我遇到了麻烦FuncAnimation在 matplotlib animation 库中 所以我决定每次渲染一个曲面图
  • PHP 重命名数组的键

    如何重命名数组中的键 从这个名为 start array 的数组开始 0 gt date gt 2012 05 01 revenue gt 100 1 gt date gt 2012 05 02 revenue gt 200 并更改 日期
  • 为什么 Java 8 中的 Cloneable 没有默认的 clone()

    CloneableJava 本质上是破碎的 具体来说 我对接口的最大问题是它需要一种不定义方法本身的方法行为 所以如果遍历一个Cloneable列表中您必须使用反射来访问其定义的行为 然而 在 Java 8 中 我们现在有了默认方法 现在我