Je suis tombé sur un problème intéressant (et très frustrant) avec la equals()méthode aujourd'hui, ce qui a provoqué le crash de ce que je pensais être une classe bien testée et un bug qui m'a pris beaucoup de temps à retrouver.
Juste pour être complet, je n'utilisais pas un IDE ou un débogueur - juste un bon éditeur de texte à l'ancienne et System.out. Le temps était très limité et c'était un projet scolaire.
De toute façon -
Je développais un panier de base qui pourrait contenir un ArrayListdes Bookobjets . Afin de mettre en œuvre les addBook(), removeBook()et les hasBook()méthodes du panier, je voulais vérifier si le Bookexistait déjà dans le Cart. Alors je pars -
public boolean equals(Book b) {
... // More code here - null checks
if (b.getID() == this.getID()) return true;
else return false;
}
Tout fonctionne bien dans les tests. Je crée 6 objets et les remplis de données. Faites beaucoup d'ajouts, de suppressions, d'opérations has () sur le Cartet tout fonctionne bien. J'ai lu que vous pouvez avoir equals(TYPE var)ouequals(Object o) { (CAST) var } mais supposer que puisque cela fonctionnait, cela n'avait pas trop d'importance.
Ensuite, j'ai rencontré un problème - je devais créer un Bookobjet avec uniquement le IDcontenu de la classe Book. Aucune autre donnée n'y serait introduite. Fondamentalement, ce qui suit:
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);
}
Du coup, la equals(Book b)méthode ne fonctionne plus. Cela a pris TRÈS longtemps à traquer sans un bon débogueur et en supposant que la Cartclasse était correctement testée et correcte. Après avoir permuté la equals()méthode à la suivante:
public boolean equals(Object o) {
Book b = (Book) o;
... // The rest goes here
}
Tout a recommencé à fonctionner. Y a-t-il une raison pour laquelle la méthode a décidé de ne pas prendre le paramètre Book alors qu'il s'agissait clairement d' un Bookobjet? La seule différence semblait être qu'elle était instanciée à partir de la même classe et remplie uniquement avec un membre de données. Je suis très très confus. S'il vous plaît, faites la lumière?