覆盖 java equals() 方法 - 不起作用?

2022-08-31 07:30:14

我今天在方法上遇到了一个有趣(而且非常令人沮丧)的问题,导致我认为是经过良好测试的类崩溃并导致一个错误,我花了很长时间才找到它。equals()

只是为了完整性,我没有使用IDE或调试器 - 只是老式的文本编辑器和System.out的。时间非常有限,这是一个学校项目。

无论如何 -

我正在开发一个基本的购物车,它可以包含一个 ArrayList of Book 对象。为了实现 Cart 的 、 和 方法,我想检查 .所以我走了 ——addBook()removeBook()hasBook()BookCart

public boolean equals(Book b) {
    ... // More code here - null checks
    if (b.getID() == this.getID()) return true;
    else return false;
}

在测试中一切正常。我创建了6个对象并用数据填充它们。对 执行许多添加、删除、has() 操作,一切正常。我读到你可以equals(TYPE var)equals(Object o){(CAST)var},但假设既然它正在工作,它就无关紧要了。Cart

然后我遇到了一个问题 - 我需要从Book类中创建一个只有其中的对象。不会向其中输入其他数据。基本上如下:BookID

public boolean hasBook(int i) {
    Book b = new Book(i);
    return hasBook(b);
}

public boolean hasBook(Book b) {
    // .. more code here
    return this.books.contains(b);
}

突然之间,该方法不再有效。这需要很长时间才能在没有一个好的调试器的情况下进行跟踪,并假设该类已经过适当的测试和正确。将方法拭子后,将方法扫描到以下内容:equals(Book b)Cartequals()

public boolean equals(Object o) {
    Book b = (Book) o;
    ... // The rest goes here   
}

一切又开始工作了。该方法决定不采用 Book 参数(即使它显然是一个对象是有原因的吗?唯一的区别似乎是它是从同一类内部实例化的,并且只填充了一个数据成员。我非常非常困惑。请放一些光?Book


答案 1

在 Java 中,继承自的方法是:equals()Object

public boolean equals(Object other);

换言之,参数的类型必须为 。这称为覆盖;您的方法执行所谓的重方法。Objectpublic boolean equals(Book other)equals()

使用重写方法来比较内容(例如,对于其和方法),而不是重载的方法。在大多数代码中,调用未正确覆盖 的等号是可以的,但与 不兼容。ArrayListequals()contains()equals()ObjectArrayList

因此,未正确覆盖该方法可能会导致问题。

我每次都覆盖等于以下内容:

@Override
public boolean equals(Object other){
    if (other == null) return false;
    if (other == this) return true;
    if (!(other instanceof MyClass)) return false;
    MyClass otherMyClass = (MyClass)other;
    ...test other properties here...
}

使用注释可以帮助很多愚蠢的错误。@Override

每当您认为您正在重写超类或接口的方法时,请使用它。这样,如果您以错误的方式执行此操作,则会收到编译错误。


答案 2

如果您使用eclipse,只需转到顶部菜单即可

Source --> Generate equals() 和 hashCode()


推荐