【问题标题】:Why does equals() in Java must be passed Object as a parameter?为什么Java中的equals()必须传入Object作为参数?
【发布时间】:2014-10-21 08:43:25
【问题描述】:

当我们在 Java 中重写 equals() 方法时,我知道 Object 需要作为参数,但我想知道 - 为什么是 Object?。

其次,假设我们覆盖hashcode()并实现equals(),但是将equals()中的参数设置为MyClass而不是ObjectMyClass是我们覆盖其equals()方法的类)。如果我们使用HashMap,我们还会得到预期的行为吗?

更新:是的,它将重载而不是覆盖。但是如果我们使用HashMap 和重载的equals() 会发生什么?另外,我在相关帖子中找不到答案。或者我错过了什么明显的东西?

【问题讨论】:

  • "实现 equals() 但将 equals() 中的参数设置为 MyClass 而不是 Object" --> 那么你就没有覆盖 equals
  • 我不完全确定链接的 URL 是否回答了关于为什么 Object 是参数的 OP 问题
  • @seteropere 我刚刚经历过,但我也没有找到答案。

标签: java object hashmap equals hashcode


【解决方案1】:

如果你编写一个参数不是 Object 的 equals() 方法,你是在重载该方法,而不是覆盖它。

现在,HashMap - HashMap 调用等于比较键。比较键的类型是Object。因此,如果您定义一个equals() 方法,其参数不是Object,则该方法将被HashMap 忽略。

我尝试了以下代码:

public class SomeClass
{
    int privateMember;

    // note it's important to override hashCode, since if the hashCode of two
    // keys is not the same, equals() won't be called at all
    public int hashCode ()
    {
        return privateMember;
    }

    public boolean equals (Object other)
    {
        if (other instanceof SomeClass) {
            return this.privateMember==((SomeClass)other).privateMember;
        }
        else { 
            return false;
        }
    }

    public static void main(String[] args)
    {
        HashMap<SomeClass,String> map = new HashMap<SomeClass,String>();
        SomeClass s1 = new SomeClass ();
        SomeClass s2 = new SomeClass ();
        s1.priv=4;
        s2.priv=4;
        map.put (s1, "something");
        if (map.containsKey (s2)) {
            System.out.println ("found!");
        } else {
            System.out.println ("not found!");
        }
    }
}

此代码输出“找到!”。

现在,如果您运行完全相同的代码,但将 equals 方法替换为:

    public boolean equals (SomeClass other)
    {
        if (other instanceof SomeClass) {
            return this.privateMember==((SomeClass)other).privateMember;
        }
        else { 
            return false;
        }
    }

输出将是“未找到!”,这意味着我们的 equals 方法被忽略了。

【讨论】:

  • 确实如此,但我们是否会出现与链接 URL 中提到的 HashMap 相同的意外行为?
  • 当然。 HashMap 需要连接到 Object.equals 的东西,它必须接受 Object 类型的输入。
  • 感谢 Eran 和 Ashley-frieze 的回答。很有帮助。我想我现在明白了。
【解决方案2】:

集合使用 Object 基类中的 equals 和 hashcode 方法。因此,您必须覆盖它们才能让您的自定义类提供实现。如果您愿意,可以重载 equals,这适用于某些代码知道它正在处理 MyClass 的实例的情况。但是,这会产生误导。

所有集合类都设计为与 Object 的实例一起使用,并且 Object 提供了一个通用的 equals 方法。

您实际上不需要直接编写 equals 方法。您可以使用 IDE 生成一个,也可以使用 Apache Commons (https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/builder/EqualsBuilder.html) 的 EqualsBuilder 来帮助将它们组合在一起。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    • 2010-09-23
    • 1970-01-01
    • 2019-06-20
    • 2014-05-15
    相关资源
    最近更新 更多