Сегодня я столкнулся с интересной (и очень расстраивающей) проблемой с методом equals(), которая вызвала сбой того, что я считал хорошо протестированным классом, и вызвавшую ошибку, на отслеживание которой у меня ушло очень много времени.
Для полноты картины я не использовал IDE или отладчик - только старый добрый текстовый редактор и System.out. Времени было очень мало, и это был школьный проект.
Во всяком случае -
Я разрабатывал базовую корзину для покупок, которая могла содержать ArrayList из Book объектов. Чтобы реализовать методы 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 }, но предполагал, что, поскольку он работает, это не имеет большого значения.
Затем я столкнулся с проблемой - мне нужно было создать объект Book с только ID в нем из класса Book. Никакие другие данные в него вноситься не будут. В основном следующие:
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() на следующий:
public boolean equals(Object o) {
Book b = (Book) o;
... // The rest goes here
}
Все снова заработало. Есть ли причина, по которой метод решил не принимать параметр Book, даже если он явно был объектом Book? Единственная разница, казалось, заключалась в том, что он был создан из одного и того же класса и заполнен только одним членом данных. Я очень запутался. Пожалуйста, пролейте немного света?