2010-04-09 7 views
9

Sono all'oscuro qui ...FindBugs - come risolvere 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: } 

In linea 6 che ricevo da FindBugs: Bug: net.blabla.SqlFixer$ForeignKeyConstraint defines compareTo(SqlFixer$ForeignKeyConstraint) and uses Object.equals()

Link to definition

Non so come correggere questo .

risposta

13

Questo errori significa che non si sta ignorando equals in ForeignKeyConstraint (e ereditando così la equals da Object) in modo che il seguente non è vero (dal javadoc di compareTo):

Si raccomanda vivamente, ma non strettamente richiesto che (x.compareTo(y)==0) == (x.equals(y)). In generale, qualsiasi classe che implementa l'interfaccia Comparable e viola questa condizione dovrebbe indicare chiaramente questo fatto. La lingua consigliata è "Nota: questa classe ha un ordinamento naturale che è incoerente con gli uguali".

Per fissare il controllo FindBugs, override equals - e hashCode - se ha un senso che è generalmente il caso (o escludere il controllo per questa classe e documentare che la classe viola questa condizione utilizzando la nota suggerito).

2

Hai provato a sovrascrivere anche il metodo di uguale in SqlFixer.ForeignKeyConstraint?

Credo che la base dell'avviso sia che, come indicato nella definizione, possono accadere cose strane se si sostituisce il confronto con e non è uguale.

Per ulteriori informazioni, consultare Joshua Bloch's Effective Java, 2nd Edition. L'articolo 12 approfondisce i dettagli dell'attuazione di Comparable e alcune delle cose a cui prestare attenzione.

4

È possibile risolverlo implementando un metodo equals(). Fare riferimento alla definizione FindBugs:

"In genere, il valore di compareTo deve restituire zero se e solo se equals restituisce true. Se viene violato, si verificheranno errori bizzarri e imprevedibili in classi come PriorityQueue."

"È fortemente consigliato, ma non strettamente richiesto (x.compareTo (y) == 0) == (x.equals (y))."

Un altro esempio è TreeSet. Implementa controlli di uguaglianza invocando compareTo e un'implementazione compareTo che è incoerente con gli uguali rende TreeSet violare il contratto dell'interfaccia Set, che potrebbe portare a malfunzionamento del programma.

4

Ti sta dicendo che c'è il potenziale per compareTo() e uguale() per non essere d'accordo. E loro, in realtà, non dovrebbero mai essere in disaccordo.

Il metodo equals() viene ereditato da java.lang.Object, che per impostazione predefinita verifica se due oggetti sono identici all'istanza . Il tuo metodo compareTo è il confronto tra oggetti basati su tableName e fkFieldName. Quindi ti troverai potenzialmente in una situazione in cui compareTo dice che due oggetti sono uguali (perché tableName e fkFieldName corrispondono), ma equivale a stati che sono diversi (perché sono istanze diverse).

Ci sono alcune API java che dipendono da compareTo ed equals che sono consistenti; questo fa parte del linguaggio java ed è considerato un contratto linguistico di base. Idealmente implementare un metodo equals (e hashcode) per verificare l'uguaglianza in base a tableName e fkFieldName.

0

Findbugs è soddisfatto:

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() { 
    ... 
} 
Problemi correlati