网站开发工程师考试,知识付费做的最好的平台,上虞区建设局网站,江苏外贸网站建设推广几个月前#xff0c;我读了一篇题为“确定Java等价性的新时代#xff1f;”的博客文章。 这在某种程度上与我当时在我那令人脚的副项目Java :: Geci中开发的内容非常吻合 。 我建议您暂停阅读#xff0c;阅读原始文章#xff0c;然后再返回此处#xff0c;即使您知道一定比… 几个月前我读了一篇题为“确定Java等价性的新时代”的博客文章。 这在某种程度上与我当时在我那令人脚的副项目Java :: Geci中开发的内容非常吻合 。 我建议您暂停阅读阅读原始文章然后再返回此处即使您知道一定比例的读者也不会回来。 这篇文章是关于如何在Java中正确实现equals()和hashCode() 以及一些有关应该如何实现或应该如何实现的思想。 在本文中我将为那些不阅读原始文章的人详细介绍这些内容并补充我的想法。 部分使用Java :: Geci的方式解决了这些问题并且在本文结尾处应如何在equals()和hashCode()处理递归数据结构。 请注意就在我阅读文章的那一天我也在完善mapper生成器以处理递归数据结构。这与我实际上正在解决的问题非常共鸣。 如果您回来甚至没有读完原始文章甚至连Liam Miller-Cushon所引用的JDK信函中的标题为“ 等效性 ”在这里您都可以从我的角度对最重要的陈述进行简短总结/从中学习文章 手动生成equals()和hashCode()很麻烦。 自Java 7以来JDK就提供了支持但是仍然存在方法的代码并且必须对其进行维护。 IDE可以为这些方法生成代码但是重新生成它们仍不是自动化过程而手动执行重新生成是容易出错的维护过程。 又名您忘记了运行发电机 Liam Miller-Cushon的标题为“ Equivalence ”的JDK信件列出了equals()和hashCode()实现中的典型错误。 值得在更多细节中重申这些内容。 某些文字被逐字引用。 “覆盖Object.equals但不覆盖hashCode。 Object.hashCode的合同规定如果两个对象相等则在两个对象中的每个对象上调用hashCode方法必须产生相同的结果。实现equals而不是hashCode使得情况不太可能。”这是一个菜鸟错误您可能会说您永远不会犯错。 是的如果您是高级程序员但在智力方面还不是高级例如忘记了牙齿修复的位置那么您永远不会忘记在创建hashCode()时创建hashCode() equals() 。 但是请注意这是生命中非常短暂的时间。 许多初级人员也构成了代码库缺少的hashCode()可能总是潜伏在Java代码的干草堆深处我们必须使用所有经济上可行的措施来避免它们不存在。 “等于无条件递归的实现。” 这是一个常见的错误甚至老年人也多次忽略了这个可能的错误。 因为我们使用的数据结构通常不是递归的所以这几乎不是问题。 当它们是递归的时 equals()或hashCode()方法的粗心的递归实现可能会导致无限循环堆栈溢出和其他不便之处。 我将在文章结尾讨论这个话题。 “比较不匹配的字段或吸气剂对例如a that.a b that.a. “这是一个主题输入错误很容易像主题-典型那样被忽略。 等于在给定null参数时抛出NullPointerException的实现。 它们应该返回false。 等于在给定类型错误的参数时抛出ClassCastException的实现。 它们应该返回false。 通过委派给hashCode()来实现equals() hashCode() 。 哈希经常冲突因此将导致误报。 考虑未在相应的equals()方法中测试的hashCode()中的状态。 相等的对象必须具有相同的hashCode() 。 将引用相等或hashCode()用于数组成员的equals()和hashCode()实现。 他们可能打算使用值相等和hashCode() 。 其他错误不在建议的范围之内使用错误例如比较两个静态不同的类型或带有定义的非本地错误例如覆盖等号和更改语义破坏可替换性 我们如何避免这些错误 一种可能性是增强语言如所提到的建议所建议的那样以便可以以声明的方式描述方法hashCode()和equals() 而实际的实现是常规且麻烦的由编译器完成。 这是光明的未来但我们必须等待。 Java因Swift整合思想而闻名。 当实现某些功能时它将以向后兼容的方式永久保存。 因此选择是快速实施它可能以错误的方式实施并永久使用它。 或等到业界完全确定必须以哪种语言实现它然后再到那时再实现它。 Java正在遵循第二种开发方式。 正如我在《 您的代码是多余的... 》一文中所描述的那样这是语言发展引起的语言短缺。 暂时性的短缺将在以后解决但就目前而言我们必须处理这种短缺。 解决这种短缺的方法之一就是代码生成这就是Java :: Geci出现的地方。 Java :: Geci是一个代码生成框架非常适合创建代码生成器以帮助减少针对特定领域问题的代码冗余。 代码生成器在单元测试执行期间运行这可能会稍晚一些因为代码已被编译。 但是此问题已通过以下方式修复如果“测试”的代码生成了任何代码并执行了编译则生成“测试”的代码将失败并且第二次测试也将不再失败。 旁注这种工作方式可能对任何软件开发人员都非常熟悉让我们再次运行它可能会起作用 从技术的角度来看在编程语言发展不足的情况下Java :: Geci也是一样。 出于特定领域的原因而生成的代码与出于语言演进不足的原因而生成的代码之间没有技术上的区别。 但是在语言演变问题的情况下您可能会找到其他也可以解决该问题的代码生成工具。 要生成equals()和hashCode() 可以使用集成开发环境。 没有什么比从IDE中选择菜单然后单击单击“生成等于和hashCode”更简单了。 假设生成的代码行为良好这可以解决以上所有问题之一。 唯一的问题是无论何时更新代码它都不会再次运行代码生成器来更新生成的代码。 IDE无法与Java :: Geci竞争。 设置Java :: Geci框架的步骤比单击几个菜单项要多。 您需要测试依赖项必须创建一个单元测试方法并且必须注释需要生成器的类或者作为替代您必须在包含生成代码的代码中插入一个编辑器折叠块。 但是在那之后您可以忘记生成器而无需担心团队中的任何开发人员都忘记了重新生成equals()或hashCode()方法。 带走 为一个类拥有适当的equals()和hashCode()方法并不像看起来那样简单。 手动编写它们几乎不是最好的方法。 使用生成工具来生成它们并确保所生成的代码和代码生成不会出现上述任何常见错误。 如果只需要QD则使用IDE菜单并生成方法。 另一方面如果您有一个较大的代码库并且有许多开发人员在其中工作并且代码生成可能需要重新执行则可以使用自动执行代码生成的工具。 示例Java :: Geci。 使用最新版本的工具例如Java以免落后于可用技术。 翻译自: https://www.javacodegeeks.com/2019/10/a-new-era-for-determining-equivalence-in-java.html