首页 > 解决方案 > 通过使它们抽象来强制实现 hashCode 和 equals 是否有任何优势?

问题描述

我刚刚偶然发现了声明abstract AbstractUnit的 uom-se 项目

// //////////////////////////////////////////////////////////////
// Ensures that sub-classes implements hashCode/equals method.
// //////////////////////////////////////////////////////////////

@Override
public abstract int hashCode();

@Override
public abstract boolean equals(Object that);

要么框架需要hashCode,要么在equals内部检查相等性,然后实现应该在框架本身中完成,或者由用户决定是否覆盖这些方法。在后一种情况下,无论如何都必须对任何Java 类进行此决定,因为它的实现方式Object以及身份和相等比较在 Java 和一般编程中的含义。那么这样的声明的目的是什么?

这听起来像是一种反模式,因为对于知道自己在做什么的程序员来说,声明是不必要的,并且会引诱那些不使用它的程序员来覆盖它super.equals/hashCode或创建他们不需要或不想要的实现。

标签: javaabstract-classequalsabstracthashcode

解决方案


你说过:

在后一种情况下,无论如何都必须为任何 Java 类做这个决定......

确实需要这样做,但是没有这些声明,没有什么能强迫子类的作者AbstractUnit实际这样做,因为Object. 因此,该声明的目的是迫使子类的作者实现hashCodeequals酌情适用于他们的子类,而不是将它们排除在外。这至少消除了子类作者甚至没有考虑需要这样做的常见错误原因。(遗憾的是,它不能消除第二个常见的错误原因:作者这样做不正确。)


重新编辑:

这闻起来像反模式......

它是否是反模式是一个见仁见智的问题,因此对于 SO 来说是题外话。

...因为声明对于知道自己在做什么的程序员来说是不必要的...

许多作者理解以兼容的方式覆盖两者的必要性equals已经hashCode非常成熟

...并引诱那些不使用它的人super.equals/hashCode

他们不能。super的版本是abstract.

...或创建他们不需要或不想要的实现。

显然,如果他们正在编写 的子类AbstractUnit,他们确实需要实现equalsand hashCode; 的作者AbstractUnit显然已经确定 A) from 的版本Object不能与AbtractUnit' 的逻辑正常工作,并且 B) 他们不能提供合理的默认值。所以他们强迫子类作者以他们唯一能做到的方式来实现它们:通过声明它们abstract


推荐阅读