154 votes

Remplacement de la méthode jaw equals () quirk

J'ai couru dans une intéressante (et très frustrant) problème avec la méthode equals() aujourd'hui, ce qui a causé ce que je pensais être un bien testé la classe de crash et de provoquer un bug qui m'a pris un temps très long à repérer.

Juste pour être complet, je n'étais pas à l'aide d'un IDE ou un débogueur - juste de la bonne vieille éditeur de texte et du Système.out. Le temps était très limité et que c'était un projet d'école.

De toute façon -

J'ai été l'élaboration d'une base panier pouvant contenir une liste de tableaux de Réserver des objets. Afin de mettre en œuvre les addBook(), removeBook(), et hasBook() les méthodes de la Charrette, je voulais vérifier si le Livre existait déjà dans le panier. Donc me voilà -

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

Tous fonctionne très bien dans les tests. J'ai créer 6 objets et de les remplir avec des données. Faire beaucoup de ajoute, supprime, a() opérations sur le Panier et tout fonctionne bien. J'ai lu que vous pouvez avoir equals(TYPE var) ou equals(Object o) { (CAST) var } mais suppose que depuis qu'il travaillait, il n'a pas trop d'importance.

Ensuite, j'ai couru dans un problème - j'avais besoin de créer un Livre-objet avec seulement l'ID de l'intérieur de la classe Book. Pas d'autres données serait entré en elle. Essentiellement les suivantes:

public boolean hasBook(int i) {
    Book b = new Book(i);
    return hasBook(b);
}

public boolean hasBook(Book b) {
    // .. more code here
    return this.equals(b);
}

Tout d'un coup, la equals(Livre b) méthode ne fonctionne plus. Cela a pris un temps TRÈS long à repérer sans un bon débogueur et en supposant que la classe Cart a été testé correctement et de les corriger. Après swaapping la méthode equals() pour les éléments suivants:

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

Tout a commencé à travailler à nouveau. Est-il une raison, la méthode décidé de ne pas prendre le Livre paramètre, même si elle a clairement été un Livre-objet? La seule différence semble être que c'était instancié à partir de l'intérieur de la même classe, et remplis avec un membre de données. Je suis très très confus. S'il vous plaît, jeter un peu de lumière?

335voto

jjnguy Points 62123

En Java, l' equals() méthode héritée d' Object est:

public boolean equals(Object other);

En d'autres termes, le paramètre doit être de type Object.

L' ArrayList utilise la bonne méthode equals, où vous avez été toujours à l'appel de celui qui n'avait pas bien remplacer Objects'égal à égal.

Pas de substitution de la méthode correctement peut causer des problèmes.

Je remplace est égale à la suivante chaque fois que:

@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...
}

L'utilisation de l' @Override d'annotation peut aider une tonne avec des erreurs stupides.

A utiliser quand vous pensez que vous êtes remplacement d'une super-classe ou de l'interface de la méthode. De cette façon, si vous le faites mal, vous obtiendrez une erreur de compilation.

110voto

Fred Points 518

Si vous utilisez eclipse juste aller au menu principal

Source--> Generate equals() et hashCode()

46voto

Julie Points 3850

11voto

Phill Sacre Points 16238

Légèrement hors-sujet à votre question, mais c'est probablement la peine de mentionner quand même:

Commons Lang a obtenu quelques excellentes méthodes que vous pouvez utiliser en remplaçant equals et hashcode. Découvrez EqualsBuilder.reflectionEquals(...) et HashCodeBuilder.reflectionHashCode(...). M'a sauvé beaucoup de maux de tête dans le passé - même si bien sûr, si vous voulez juste faire "est synonyme de" ID il peut ne pas convenir à votre situation.

Je suis aussi d'accord que vous devriez utiliser l' @Override d'annotation lorsque vous êtes primordial est égal à (ou toute autre méthode).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X