java - 调用 super.equals 的递归 .equals 方法

标签 java equals

编辑

我做的很差,给任何人提供了不完整的信息来确定我的问题的原因。真正的问题是我在 Animal 中有一个嵌套类,它有自己的 .equals,在其外部类型上调用 .equals。 (因此调用 .equals on animal 从嵌套类的 .equals 调用 .equals on animal)。


我在继承树中有三个类。假设它们是 Animal --> Dog<Owner> --> DogWithHumanOwner .

所以 DogWithHumanOwner 是通用 Dog 的一个实现,它的主人专门有一个 Human。

我已经覆盖了 Animal 和 Dog 的 .equal 方法。 Dog 的 .equal 方法如下所示:

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (!super.equals(obj))
        return false;

    [other stuff]

    return true;
}

不过我实际使用的是 DogWithHumanOwner。似乎当我尝试比较两个 DogWithHumanOwner 的相等性时,dogWithHumanOwner 继承了 Dog<Owner> 中的 equals 方法。 ,它调用 super.equals,这是 dogWithHumanOwner 的父类(super class)的 .equals 方法,这是它所在的方法,因此它会导致递归循环和计算器溢出。

(我不需要比较 Dog<Owner> 类的实现的任何特定属性,因为我在 Dog<Owner> 中这样做并且所有者需要有适当的 equals 方法。)

编写 .equals 方法以避免此问题的最佳做法是什么?我在画一个空白。我是否应该完全不调用 super 而手动测试相等性?

编辑:我不得不删除 BlackLabs,因为我想用 blackLabs 做这件事没有意义。

最佳答案

编辑后编辑:

简而言之,是的,根本不要调用 super.equals。此外,请确保 super.equals 使用类相等性而不是 instanceof 检查其传入对象的类。这就是 Object.equals 默认情况下所做的,所以如果 Animal 没有声明一个 equals,你很好。

不过,我的其余回答仍然是相关的,因为以上基本上是对上一段结论的总结,就像之前一样。基本上,如果父类(super class)不需要等于子类的实例,那么每个人都可以检查对象是否相等(不是 instanceof)以及他们想要的任何状态。如果父类(super class)只检查 instanceof(不是更严格的相等性),那么基本上子类不能检查父类(super class)检查之外的任何额外状态。

在您的例子中,Animal 不检查任何东西,而 Dog 会。所以你可以开始了。

原回答如下:


如果 (a) 它们在某些特定的 BlackLab 品质上相等,并且 (b) 它们在 Dogness 上相等,您是否认为两个 BlackLab 相等?如果是这样,这是一个坏主意!它打破了 Object.equals 指定的相等的传递属性.想象一下你有:

  • 黑实验室
  • 黑实验室
  • 狗c

假设这三个人的“狗性”相同,例如他们的体重、高度和名字。但这两个 BlackLab 的 BlackLabness 并不相同,例如它们外套的光泽。现在你有:

  • a = c
  • b = c
  • a != b//打破传递性!

另一方面,如果 BlackLab.equals 没有添加任何额外的检查——那么您根本不需要覆盖它。它只会继承 Dog 的平等性,这就是您想要的。

正如 Mattias Buelens 指出的,您可以通过更严格的类型检查来解决这个问题——要求两个对象属于同一类,而不是使用 instanceof。这修复了平等契约,但代价是体重 80 磅的 BlackLab“Rex”不等于体重 80 磅的名为“Rex”的未指定品种的狗。如果您考虑所需的特定用例,您可能会发现这是完全可以接受的。

关于java - 调用 super.equals 的递归 .equals 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366797/

相关文章:

java - 在 Java 程序之间传递 POJO 最简单的框架是什么?

java - U0670 支持黑莓开发

C# SortedSet<T> 和相等性

java - 理解equals方法

java - 有什么方法可以继承不是@MappedSuperclass 的实体?

java - Web 应用程序创建了一个 ThreadLocal,但未能将其删除 Tomcat [SEVERE]

java - 用Maven目录结构的Maven工程源码生成jar?

java - 覆盖自引用父子对象的等于

php - 等于 SQL 的 %like% 但在 PHP 中

java - 单元测试等于和哈希码 - 一个复杂的故事