返回

自定义equals方法不调用父类equals:风险与解决方案

后端

在 Java 中,equals 方法用于比较两个对象的相等性。它是一个非常重要的方法,在各种场景下都会用到,例如集合中的元素比较、Map 中的键值比较等等。

当我们自定义 equals 方法时,通常会忽略调用父类的 equals 方法。这可能会带来一些问题,特别是当父类也定义了自己的 equals 方法时。

例如,假设我们有一个 Animal 类,它定义了一个 equals 方法来比较两个动物是否相等。

public class Animal {

    private String name;

    public boolean equals(Object obj) {
        if (obj instanceof Animal) {
            Animal other = (Animal) obj;
            return this.name.equals(other.name);
        }
        return false;
    }
}

现在,我们有一个 Dog 类继承了 Animal 类,并且我们也定义了一个 equals 方法来比较两个狗是否相等。

public class Dog extends Animal {

    private String breed;

    public boolean equals(Object obj) {
        if (obj instanceof Dog) {
            Dog other = (Dog) obj;
            return super.equals(other) && this.breed.equals(other.breed);
        }
        return false;
    }
}

在这种情况下,如果我们在 Dog 类的 equals 方法中没有调用 super.equals(other),那么两个 Dog 对象的比较将只考虑它们的 breed 属性,而忽略了它们的 name 属性。这可能会导致错误的结果。

为了避免这种情况,我们应该在 Dog 类的 equals 方法中调用 super.equals(other)。这将确保父类的 equals 方法也会被调用,从而比较两个动物的 name 属性。

public class Dog extends Animal {

    private String breed;

    public boolean equals(Object obj) {
        if (obj instanceof Dog) {
            Dog other = (Dog) obj;
            return super.equals(other) && this.breed.equals(other.breed);
        }
        return false;
    }
}

通过调用 super.equals(other),我们可以确保 Dog 类的 equals 方法既考虑了 breed 属性,也考虑了 name 属性。这将使比较结果更加准确和一致。

因此,在自定义 equals 方法时,我们应该始终调用父类的 equals 方法。这将确保子类的 equals 方法能够正确比较对象,并与父类的 equals 方法保持一致。