2010-04-09 23 views
9

estoy aquí ... ni ideaFindBugs - cómo resolver 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: } 

En la línea 6 que obtenemos de FindBugs: Bug: net.blabla.SqlFixer$ForeignKeyConstraint defines compareTo(SqlFixer$ForeignKeyConstraint) and uses Object.equals()

Link to definition

No sé cómo corregir este .

Respuesta

13

Este error significa que no se está anulando equals en ForeignKeyConstraint (y así heredar el equals de Object) por lo que el siguiente no es verdad (desde el javadoc de compareTo):

Se recomienda encarecidamente, pero no se requiere estrictamente que (x.compareTo(y)==0) == (x.equals(y)). En términos generales, cualquier clase que implemente la interfaz Comparable y viole esta condición debe indicar claramente este hecho. El lenguaje recomendado es "Nota: esta clase tiene un orden natural que es inconsistente con los iguales".

para fijar el cheque FindBugs, anulan equals - hashCode y - si tiene sentido que generalmente es el caso (o excluir la comprobación de esta clase y su clase de documento que viole esta condición mediante la nota sugerido).

2

¿Has probado sobreescribiendo el método igual también en SqlFixer.ForeignKeyConstraint?

Creo que la advertencia se basa en que, como se indica en la definición, pueden suceder cosas extrañas si anula compareTo y no es igual.

Para obtener más información, consulte Joshua Bloch's Effective Java, 2nd Edition. El ítem 12 profundiza sobre los pormenores de la implementación de Comparable y algunas de las cosas a las que hay que prestarle atención.

4

Puede resolverlo implementando un método equals(). Consulte la definición FindBugs:

"En general, el valor de compareTo debe devolver cero si y solo si iguala devuelve verdadero. Si esto se infringe, se producirán fallas extrañas e impredecibles en clases como PriorityQueue".

"Se recomienda encarecidamente, pero no estrictamente, que (x.compareTo (y) == 0) == (x.equals (y))."

Otro ejemplo es TreeSet. Implementa comprobaciones de igualdad al invocar compareTo, y una implementación compareTo que es inconsistente con equals hace que TreeSet viole el contrato de la interfaz Set, lo que puede llevar a un mal funcionamiento del programa.

4

Te dice que existe la posibilidad de que compareTo() y equals() no estén de acuerdo. Y deberían, realmente, nunca estar en desacuerdo.

El método equals() se hereda de java.lang.Object, que comprueba por defecto si dos objetos son el mismo instancia. Su método compareTo está comparando objetos basados ​​en tableName y fkFieldName. Por lo tanto, potencialmente se encontrará en una situación donde compareTo establece que dos objetos son iguales (porque tableName y fkFieldName coinciden), pero equivale a estados son diferentes (porque son instancias diferentes).

Hay algunas API de Java que dependen de compareTo y son consistentes; esto es parte del lenguaje Java y se considera un contrato de lenguaje central. Lo ideal sería implementar un método equals (y hashcode) para verificar la igualdad en base a tableName y fkFieldName.

0

Findbugs está contento con:

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() { 
    ... 
} 
Cuestiones relacionadas