覆盖 java equals() 方法 - 不起作用? [英] Overriding the java equals() method - not working?

查看:39
本文介绍了覆盖 java equals() 方法 - 不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天在 equals() 方法中遇到了一个有趣(并且非常令人沮丧)的问题,这导致我认为是经过良好测试的类崩溃并导致了一个错误,这让我非常沮丧很长时间追查.

I ran into an interesting (and very frustrating) issue with the equals() method today which caused what I thought to be a well tested class to crash and cause a bug that took me a very long time to track down.

为了完整起见,我没有使用 IDE 或调试器 - 只是很好的老式文本编辑器和 System.out.时间非常有限,而且是学校的项目.

Just for completeness, I wasn't using an IDE or debugger - just good old fashioned text editor and System.out's. Time was very limited and it was a school project.

无论如何 -

我正在开发一个基本的购物车,它可以包含一个 Book 对象的 ArrayList.为了实现 Cart 的 addBook()removeBook()hasBook() 方法,我想检查 code>Book 已经存在于 Cart 中.所以我走了 -

I was developing a basic shopping cart which could contain an ArrayList of Book objects. In order to implement the addBook(), removeBook(), and hasBook() methods of the Cart, I wanted to check if the Book already existed in the Cart. So off I go -

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

在测试中一切正常.我创建了 6 个对象并用数据填充它们.在 Cart 上执行许多添加、删除、has() 操作,一切正常.我读到你可以要么有 equals(TYPE var) 要么 equals(Object o) { (CAST) var } 但假设因为它正在工作,没什么大不了的.

All works fine in testing. I create 6 objects and fill them with data. Do many adds, removes, has() operations on the Cart and everything works fine. I read that you can either have equals(TYPE var) or equals(Object o) { (CAST) var } but assumed that since it was working, it didn't matter too much.

然后我遇到了一个问题 - 我需要从 Book 类中创建一个 Book 对象,其中 only ID 在其中.不会在其中输入其他数据.基本上如下:

Then I ran into a problem - I needed to create a Book object with only the ID in it from within the Book class. No other data would be entered into it. Basically the following:

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) 方法不再有效.如果没有良好的调试器并假设 Cart 类经过正确测试和正确,这需要很长时间才能找到.将 equals() 方法替换为以下内容后:

All of a sudden, the equals(Book b) method no longer works. This took a VERY long time to track down without a good debugger and assuming the Cart class was properly tested and correct. After swaapping the equals() method to the following:

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

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

Everything began to work again. Is there a reason the method decided not to take the Book parameter even though it clearly was a Book object? The only difference seemed to be it was instantiated from within the same class, and only filled with one data member. I'm very very confused. Please, shed some light?

推荐答案

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

In Java, the equals() method that is inherited from Object is:

public boolean equals(Object other);

换句话说,参数必须是 Object 类型.这称为覆盖;您的方法 public boolean equals(Book other)equals() 方法执行所谓的重载.

In other words, the parameter must be of type Object. This is called overriding; your method public boolean equals(Book other) does what is called overloading to the equals() method.

ArrayList 使用重写的 equals() 方法来比较内容(例如,对于它的 contains()equals() 方法),不是重载的.在您的大部分代码中,调用没有正确覆盖 Object 的 equals 的代码很好,但与 ArrayList 不兼容.

The ArrayList uses overridden equals() methods to compare contents (e.g. for its contains() and equals() methods), not overloaded ones. In most of your code, calling the one that didn't properly override Object's equals was fine, but not compatible with ArrayList.

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

So, not overriding the method correctly can cause problems.

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

I override equals the following everytime:

@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 注释可以帮助解决很多愚蠢的错误.

The use of the @Override annotation can help a ton with silly mistakes.

每当您认为要覆盖超类或接口的方法时,请使用它.这样,如果你做错了,你会得到一个编译错误.

Use it whenever you think you are overriding a super class' or interface's method. That way, if you do it the wrong way, you will get a compile error.

这篇关于覆盖 java equals() 方法 - 不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆