为什么Java的Area#equals方法不覆盖Object#equals?

2024-01-31

我刚刚遇到了一个由Java引起的问题java.awt.geom.Area#equals(Area)方法。该问题可以简化为以下单元测试:

@org.junit.Test
public void testEquals() {
    java.awt.geom.Area a = new java.awt.geom.Area();
    java.awt.geom.Area b = new java.awt.geom.Area();
    assertTrue(a.equals(b)); // -> true

    java.lang.Object o = b;
    assertTrue(a.equals(o)); // -> false
}

经过一番绞尽脑汁和调试后,我终于在 JDK 源代码中看到了equals中的方法Area看起来像这样:

public boolean equals(Area other)

请注意,它确实not @Override正常的equals方法来自Object,但只是用更具体的类型重载该方法。因此,上面示例中的两个调用最终调用了不同的实现equals.

由于这种行为自 Java 1.2 以来就已经存在,因此我认为它不被视为错误。因此,我更有兴趣了解why决定是为了not正确地覆盖equals方法,但同时提供一个重载变体。 (表明这是一个实际决定的另一个暗示是没有被覆盖hashCode()方法。)

我唯一的猜测是作者担心缓慢equals区域的实现不适合在放置时比较平等Areas in Set,Map,ETC。数据结构。 (在上面的示例中,您可以添加a to a HashSet,虽然b等于a, 呼叫contains(b)会失败。)话又说回来,为什么他们不只是以一种不与诸如equals方法 ?


RealSkeptic 链接到JDK-4391558 https://bugs.openjdk.java.net/browse/JDK-4391558在上面的评论中。这该错误解释了原因:

重写 equals(Object) 的问题是你还必须 重写 hashCode() 以返回一个保证 equals() 的值 仅当两个对象的哈希码也相等时才为 true。

but:

这里的问题是 Area.equals(Area) 并没有执行非常好的操作 直接比较。它精心检查每一个 两个区域中的几何图形并测试它们是否覆盖了 相同的封闭空间。两个 Area 对象可以具有完全的 同一封闭空间的不同描述和 equals(Area) 会发现它们是相同的。

所以基本上我们留下了一系列不太令人愉快的选项,例如:

弃用 equals(Area) 并为其创建一个替代名称 操作,例如“areasEqual”,以避免混淆。 不幸的是,旧方法将保留并且可以链接和 会困住很多想要调用 equals(Object) 的人 版本。

or:

弃用 equals(Area) 并将其实现更改为完全相同 equals(Object) 以避免错误时出现语义问题 方法被调用。创建一个具有不同名称的新方法以避免 混淆实现 equals(Area) 提供的旧功能。

or:

实现 equals(Object) 来调用 equals(Area) 并实现一个虚拟对象 hashCode() 遵循退化中的 equals/hashCode 契约 通过返回一个常量的方式。这将使 hashCode 方法 本质上毫无用处,并且使 Area 对象作为键中的键几乎毫无用处 HashMap 或哈希表。

或其他方式修改equals(Area)会改变其语义或使其与hashCode.

看起来维护者认为更改此方法既不可行(因为错误注释中概述的选项都不能完全解决问题)也不重要(因为实现的方法非常慢,并且可能只会在比较时返回 true一个实例Area正如评论者所建议的那样)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么Java的Area#equals方法不覆盖Object#equals? 的相关文章

随机推荐

  • Python 中二维矩阵的单元格分配,无需 numpy

    下面是我的脚本 它基本上创建了一个 12x8 的零矩阵 其中填充了 0 然后我想将其一一填充 假设第 2 列第 0 行需要为 5 我该怎么做 下面的示例显示了我是如何做到的以及错误的 根据我的需要 输出 list MatrixRow lis
  • 为什么要禁用垃圾收集器?

    Pythons gc disable http docs python org 3 3 library gc html gc disable禁用自动垃圾收集 据我了解 这会产生相当多的副作用 为什么有人想要禁用自动垃圾收集 如果没有它 如何
  • Swift 4 中的访问控制

    升级到Swift4 from Swift3 我遇到了一些相关问题access control 这是示例代码 其中有Swift3 过去工作正常 open class MyClass private let value Int static v
  • Xcode 机器人在成功/失败时不发送电子邮件

    我设置了 Xcode Bots 它运行成功 但是 尽管设置了电子邮件地址以在构建成功或失败时收到通知 但我没有收到任何电子邮件 是否有任何额外的 SMTP 设置需要隐藏在某处 您可能需要配置 Mac OSX 服务器来发送电子邮件 本地服务器
  • 如何在 Eclipse 中根据变量设置 Ant 属性?

    我有一个常见问题 可能有无数种方法可以解决它 我正在为这种典型场景寻找一种优雅 简单的解决方案 我在 Eclipse 中有一个带有 Ant 构建文件 build xml 的项目 该构建文件使用属性文件 build properties 在该
  • NSRegularExpression 用于剥离 HTML 标签

    我正在开发一个电子书阅读器应用程序 我有整本电子书的 ePUB 文件 其中电子书的每个主题都是一个 html 文件 我想在应用程序中实现搜索功能 我正在使用 NSRegularExpression 类进行搜索 请考虑以下 html 代码
  • 为什么 C#7 语法中的 TryParse(清空参数)在编译时会发出警告?

    在 C 7 中 你可以这样做 if int TryParse 123 out int result Console WriteLine Parsed result 或者 如果您不使用结果而只想检查解析是否成功 discard https l
  • 用于复制的 EBS 卷的快照

    我在 EBS 卷上设置了一个带有 MySQL 的 EC2 实例 并设置了另一个充当复制从属实例 复制设置很好 我的问题是关于拍摄这些卷的快照 我注意到快照过程需要锁定表 这可能会给用户带来不便 因此 我的想法是保留主实例并拍摄作为从实例的快
  • 从队列中获取最后 n 个项目

    我看到的一切都是关于列表的 但这是关于events queue queue 这是一个包含我想要提取的对象的队列 但是我如何从该队列中获取最后 N 个元素 根据定义 你不能 你可以做的是使用循环或理解get the first 你不能get从
  • 为什么body.scrollHeight自动增加而不减少

    我的 iframe body 有一个scrollHeight我认为是只读的属性 我不明白它是如何设置的 当我修改iframe body innerHTML和一些largerHTML 我注意到iframe body scrollHeight
  • 如何用随机字典值填充 pandas 数据框列

    我是 Pandas 新手 我想使用随机文本数据 我正在尝试向 DataFrame df 添加 2 个新列 每个列都由从字典中随机选择的键 newcol1 值 newcol2 填充 countries Africa Ghana Europe
  • TinyMCE中通过execCommand(insertContent)插入元素的参考

    我需要一个我通过 TinyMCE 编辑器插入的元素的参考 ed execCommand mceInsertContent false span class marker my node content span 或者 是否有任何解决方法可以
  • CollapsingToolbarLayout 以编程方式扩展动画持续时间

    我在 Android 的应用程序中使用 CollapsingToolbarLayout 我的应用程序的最低要求 API 是 9 我需要当用户单击折叠的工具栏时展开折叠的工具栏 就像在最新的 Gmail 日历应用程序中一样 所以我设置了一个
  • 多用户数据源 - Spring + Hibernate

    我正在编写一个支持多个用户的网络应用程序 每个用户都有自己的数据库 使用H2 所有数据库模式都是相同的 我希望在这个应用程序中使用 Spring Hibernate 所以我被困在如何将用户的数据库与该用户关联起来 也许在HTTPSessio
  • 可对动态内容进行排序

    所以我使用 jQuery UI 可排序插件对小图库中的照片进行排序 function area sortable items sort wrapper cursor move handle photo handler opacity 0 5
  • django:如何为 SuspiciousOperation 异常创建自定义日志过滤器?

    迁移到 1 11 从 1 8 后 我收到了一些SuspiciousOperation记录错误 它似乎来自 JS 请求 如果用户移动鼠标 它会保持会话活动 但这并不重要 我怎样才能过滤这个异常 我尝试过的 我刚刚在某处创建了一个过滤器 imp
  • 限制变量范围

    我正在尝试编写一个函数 它限制 R 变量的范围 例如 source LimitScope R y 0 f function Raises an error as y is a global variable x y 我想过测试可变环境 但不
  • 我应该如何更新“热门”表?

    我有一个带有 热 表的 postgres 数据库 这意味着它每秒都会收到许多更新 删除 我想运行一个查询UPDATE大约 10 的行 我没有 10 标准的索引 隔离级别设置为SERIALIZABLE作为数据库标志 影响所有事务 我希望这个查
  • Elixir Phoenix 生产服务器出现 Letscrypt 续订问题

    我有一个使用 Elixir Phoenix 框架构建的网站 该网站在开发和生产模式下都运行良好 当phoenix服务器在开发模式下运行时 我更新Let s Encrypt证书没有问题 但是当完全一样应用程序正在生产模式下运行 尝试更新时我不
  • 为什么Java的Area#equals方法不覆盖Object#equals?

    我刚刚遇到了一个由Java引起的问题java awt geom Area equals Area 方法 该问题可以简化为以下单元测试 org junit Test public void testEquals java awt geom A