Java覆盖Object的equals()方法

8

如何覆盖对象类中的equals方法?

即我有:

class Person{

//need to override here
public boolean equals (Object obj){

}

我想将参数obj转换为Person类型,但如果我使用(Person) obj就行不通。

1
请注意,如果您有一个非最终类,则需要小心。通常,您应该使用obj.getClass() == Person而不是instanceof Person来检查运行时类。虽然可以编写使派生类型相等的合同(如java.util.List),但需要谨慎。此外,如果您重写了equals,则应该覆盖hashCode,但这可能有点超前。 - Tom Hawtin - tackline
9个回答

10

9

您可以在方法内部进行转换,只需确保使用instance of是正确的类型即可。

if(obj instanceof Person)
{
   Person otherPerson = (Person) obj;
   //Rest of the code to check equality
}
else
{
//return false maybe
}

我想到了 Person otherPerson = (Person) obj; - user69514

8
@Override
public boolean equals(Object o) 
{
    if (o instanceof Person) 
    {
      Person c = (Person) o;
      if ( this.FIELD.equals(c.FIELD) ) //whatever here
         return true;
    }
    return false;
}

4
很多我不喜欢那段代码的地方,但是我被迫要点赞 @Override - Tom Hawtin - tackline

5

请查看关于对象比较的问题

请注意,如果您覆盖了equals()方法,则必须同时覆盖hashCode()方法。equals/hashCode合同是,如果两个对象相等,则它们必须具有相同的哈希码。


3
如果您计划创建Person子类,请使用以下代码:
if(obj!=null && obj.getClass() == Person.class)
而不是使用instanceof。这段代码涉及到IT技术。

为什么会使用getClass()而不是instanceof?(只是好奇。) - Tom
2
如果Employee扩展了Person类,并且Employee有额外的字段,如id等,则使用person.equals(employee)可能会出现误报。 - saugata
1
你需要担心的不是假阳性,而是违反了自反性。无论你使用什么,你基本上可以保证 new Employee().equals(new Person()) 将会是 false(Person 不是 Employee 的实例)。如果你颠倒参数,结果必须相同,因此一个 Person 不能等于它自己的子类(除非在子类的 equals() 方法中做了一些非常奇怪的事情)。 - Andrzej Doyle
2
此外 - 我更喜欢示例代码中的 if(obj!=null && obj.getClass() == this.getClass()),因为这样可以在子类继承时正常工作。目前你回答中的示例会导致子类的实例不等于它本身(除非它重写了equals()方法),这也是错误的。 - Andrzej Doyle

2
只有在想要断言两个被比较的引用指向完全相同类的对象而不是实现相同基类的对象时,才需要使用getClass()而不是instanceof
假设我们有一个Employeee和一个Managerm(扩展自Employee)。 m instanceof Employee将返回true,m.getClass() == Employee.class将返回false。
在某些情况下,后者可能更可取,但很少在equals()hashCode()方法中比较实例。

1

对于任何字段类型,我更喜欢更简单、空安全的Objects.equals

@Override
public boolean equals(Object o) {
    if (o instanceof Person) {
        Person p = (Person) o;
        return Objects.equals(p.FIELD, this.FIELD);
    }
    return false;
}

0

还有一个需要了解的重点是,当你覆盖equals()方法(以及hashcode()方法)后,你可以像下面这样比较同一类的两个对象:

Person p1 = new Person();
Person p2 = new Person();

....

if ( p1.equals( p2 ) )

{
   // --- Two Persons are equal, w.r.t the fields you specified in equals method ---

}

0

我知道这个问题已经有答案了,但在我的实践中,我发现这是覆盖对象比较以确保全局一致性的最有效方法:

@Override
public boolean equals(Object o) {
    return o instanceof Person && this.getSomeMagicalField().equals(((Person) o).getSomeMagicalField());
}

或者如果你不是在比较字符串:

@Override
public boolean equals(Object o) {
    return o instanceof Person && this.getSomeMagicalField() == (Person) o).getSomeMagicalField();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接