equals()今天,我遇到了一个有趣(非常令人沮丧)的方法问题,该问题导致我认为是一个经过良好测试的类崩溃了,并导致了一个错误,使我花了很长时间来追踪。
equals()
为了完整起见,我没有使用IDE或调试器-只是老式的文本编辑器和System.out。时间非常有限,这是一个学校项目。
无论如何-
我开发一个基本的购物车可能包含ArrayList的Book对象。为了贯彻落实addBook(),removeBook()以及hasBook()对车的方法,我想检查,如果Book在已经存在Cart。所以我走了
ArrayList
addBook()
removeBook()
hasBook()
Book
Cart
public boolean equals(Book b) { ... // More code here - null checks if (b.getID() == this.getID()) return true; else return false; }
在测试中一切正常。我创建6个对象,并用数据填充它们。在上执行许多添加,删除,has()操作Cart,一切正常。我读到你可以拥有equals(TYPE var)或者equals(Object o) { (CAST) var }可以假设,因为它一直在起作用,所以没什么大不了的。
has()
equals(TYPE var)
equals(Object o) { (CAST) var }
然后,我遇到了一个问题-我需要创建一个Book与对象仅在ID从Book类内它。没有其他数据可以输入。基本上如下:
ID
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()方法交换为以下内容之后:
equals(Book b)
public boolean equals(Object o) { Book b = (Book) o; ... // The rest goes here }
一切重新开始。是否有一个原因,这种方法决定不采取,即使它清楚地书参数是一个Book对象呢?唯一的区别似乎是它是在同一类中实例化的,并且仅填充了一个数据成员。我非常困惑。拜托,让一些亮点?
在Java中,equals()从其继承的方法Object是:
Object
public boolean equals(Object other);
换句话说,参数必须是类型Object。
会ArrayList使用正确的equals方法,在此情况下,你始终会调用未正确覆盖Objectequals的方法。
Objectequals
未正确覆盖该方法可能会导致问题。
我每次都覆盖等于以下内容:
@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注释可以帮助解决许多愚蠢的错误。
@Override
只要你认为自己要重写超类或接口的方法,就可以使用它。这样,如果你做错了,你将得到一个编译错误。