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

查看:128
本文介绍了覆盖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.

无论如何 -

我正在开发一个基本的购物车其中可能包含 ArrayList 预订对象。为了实现 addBook() removeBook() hasBook()购物车的方法,我想检查购物车中是否已存在预订。我离开了 -

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个对象并用数据填充它们。在购物车上做了很多添加,删除,has()操作,一切正常。我读到你可以要么等于(TYPE var)等于(对象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.

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

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);
}

突然间,等于(预定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 的方法是:

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

public boolean equals(Object other);

换句话说,参数必须是 Object

In other words, the parameter must be of type Object.

ArrayList 使用正确的equals方法,在那里你总是调用那个没有'的方法正确覆盖对象的等于。

The ArrayList uses the correct equals method, where you were always calling the one that didn't properly override Object's equals.

不正确地覆盖方法会导致问题。

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 wrong you will get a compile error.

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

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