2010-04-09 18 views
9

Je suis ici désemparés ...FindBugs - comment résoudre EQ_COMPARETO_USE_OBJECT_EQUALS

1: private static class ForeignKeyConstraint implements Comparable<ForeignKeyConstraint> { 
2: String tableName; 
3: String fkFieldName; 
4: 
5: public int compareTo(ForeignKeyConstraint o) { 
6: if (this.tableName.compareTo(o.tableName) == 0) { 
7:   return this.fkFieldName.compareTo(o.fkFieldName); 
8:  } 
9:  return this.tableName.compareTo(o.tableName); 
10: } 
11: } 

Dans la ligne 6 que je reçois de FindBugs: Bug: net.blabla.SqlFixer$ForeignKeyConstraint defines compareTo(SqlFixer$ForeignKeyConstraint) and uses Object.equals()

Link to definition

Je ne sais pas comment corriger cette .

Répondre

13

Cette erreur signifie que vous n'êtes pas primordial equals dans ForeignKeyConstraint (et héritant ainsi la equals de Object) de sorte que le suivant n'est pas vrai (du javadoc de compareTo):

Il est fortement recommandé, mais pas strictement requis que (x.compareTo(y)==0) == (x.equals(y)). D'une manière générale, toute classe qui implémente l'interface Comparable et viole cette condition devrait clairement indiquer ce fait. La langue recommandée est "Note: cette classe a un ordre naturel qui est incompatible avec des égaux."

Pour fixer le chèque FindBugs, substituez equals - et hashCode - s'il est logique qui est généralement le cas (ou ne comprennent pas la vérification de cette classe et le document que votre classe ne respecte pas cette condition à l'aide de la note suggérée).

2

Avez-vous essayé d'outrepasser la méthode equals dans SqlFixer.ForeignKeyConstraint?

Je crois que la base de l'avertissement est que, comme indiqué dans la définition, des choses étranges peuvent se produire si vous surchargez compareTo et non égal.

Pour plus d'informations, consultez Joshua Bloch's Effective Java, 2nd Edition. Le point 12 approfondit les tenants et les aboutissants de la mise en œuvre de Comparable et de certaines des choses à surveiller.

4

Vous pouvez le résoudre en implémentant une méthode equals(). Reportez-vous à la définition de FindBug:

"Généralement, la valeur de compareTo doit renvoyer zéro si et seulement si equals renvoie la valeur true.En cas de violation, des échecs étranges et imprévisibles se produiront dans des classes telles que PriorityQueue."

"Il est fortement recommandé, mais pas strictement requis, que (x.compareTo (y) == 0) == (x.equals (y))."

Un autre exemple est TreeSet. Il implémente des vérifications d'égalité en appelant compareTo et une implémentation compareTo incompatible avec equals fait que TreeSet enfreint le contrat de l'interface Set, ce qui peut entraîner un dysfonctionnement du programme.

4

Il vous dit que les possibilités de compareTo() et d'égal à() ne sont pas d'accord. Et ils devraient, vraiment, ne jamais être en désaccord.

La méthode equals() est héritée de java.lang.Object, qui vérifie par défaut si deux objets sont identiques instance. Votre méthode compareTo compare les objets basés sur tableName et fkFieldName. Donc, vous vous retrouverez potentiellement dans une situation où compareTo indique que deux objets sont identiques (parce que tableName et fkFieldName correspondent), mais équivaut à des états différents (parce qu'il s'agit d'instances différentes).

Il existe quelques API java qui dépendent de compareTo et qui sont cohérentes; cela fait partie du langage Java et est considéré comme un contrat de langue principale. Idéalement, implémentez une méthode equals (et hashcode) pour vérifier l'égalité basée sur tableName et fkFieldName.

0

Findbugs est satisfait:

public int compareTo(ForeignKeyConstraint o) { 
    if (this.equals(o)) { 
     return 0; 
    } else if (this.tableName.equals(o.tableName)) { 
     // fkFieldName must be different 
     return this.fkFieldName.compareTo(o.fkFieldName); 
    } else { 
     // tableName must be different 
     return this.tableName.compareTo(o.tableName); 
    } 
} 

@Override 
public equals() { 
    ... 
} 

@Override 
public int hashCode() { 
    ... 
}