findbugs advertencia: igual método no debe asumir nada sobre el tipo de su argumento

StackOverflow https://stackoverflow.com/questions/364454

  •  21-08-2019
  •  | 
  •  

Pregunta

Cuando se ejecuta FindBugs en mi proyecto, me dieron algunos casos de error descritos anteriormente.

A saber, mis versiones imperiosas de iguales convertir el objeto RHS en el mismo tipo que el objeto en el que se define la versión de primer orden.

Sin embargo, no estoy seguro de si un mejor diseño es posible, ya que yo sepa Java no permite variación en los parámetros del método, por lo que no es posible definir cualquier otro tipo para el parámetro es igual.

¿Estoy haciendo algo muy mal, o es FindBugs demasiado ansioso?

Una forma diferente de la frase esta pregunta es: ¿cuál es el comportamiento correcto si el objeto pasa a igual no es el mismo tipo que un LHS: ¿Es esta una falsa, o debe haber una excepción

?

Por ejemplo:

public boolean equals(Object rhs)
{
    MyType rhsMyType = (MyType)rhs; // Should throw exception
    if(this.field1().equals(rhsMyType.field1())... // Or whatever
}
¿Fue útil?

Solución

Por lo general, al aplicar iguales se puede comprobar para ver si la clase del argumento es igual (o compatible) a la clase que implementa antes de depositarlo. Algo como esto:

if (getClass() != obj.getClass())
    return false;
MyObj myObj = (MyObj) obj;

Hacerlo de esta manera evitará que la advertencia FindBugs.

Una nota al margen para hacer frente a un comentario:
Algunas personas sostienen a utilizar en lugar de instanceof getClass para comprobar la seguridad de tipos. Hay un gran debate sobre eso, lo que yo estaba tratando de no entrar en cuando me di cuenta que se puede comprobar la igualdad de clases o compatibilidad, pero supongo que no puedo escapar de ella. Todo se reduce a esto - si utiliza equals puede apoyar la igualdad entre las instancias de una clase e instancias de su subclase, pero corre el riesgo de romper el contrato simétrica de <=>. En general, yo recomendaría no usar <=> a menos que sepa lo necesita y usted sabe lo que está haciendo. Para obtener más información, véase:

Otros consejos

Probablemente se esté haciendo algo como esto:

public class Foo {
  // some code

  public void equals(Object o) {
    Foo other = (Foo) o;
    // the real equals code
  }
}

En este ejemplo, usted está asumiendo algo sobre el argumento de iguales (): Usted está asumiendo que es de tipo Foo. Esto no tiene que ser el caso! También puede obtener una cadena (en cuyo caso se debe casi definitivamente return false).

Así que el código debería tener este aspecto:

public void equals(Object o) {
  if (!(o instanceof Foo)) {
    return false;
  }
  Foo other = (Foo) o;
  // the real equals code
}

(o utilizar el más estricto getClass() != o.getClass() mencionado por Dave L.

También puede ver de esta manera:

Integer i = new Integer(42);
String s = "fourtytwo";
boolean b = i.equals(s);

¿Hay alguna razón por la que este código debería lanzar una ClassCastException en lugar de terminar con normalidad y el establecimiento de b a false?

Lanzar un .equals() como respuesta a <=> no sería sensato. Porque incluso si se trata de una pregunta estúpida ( "Por supuesto, una cadena nunca es igual a un Foo!") Sigue siendo un válido uno con una respuesta perfectamente bien ( "no" == <=>).

Me gustaría recomendar a ignorar dichos findbugs de advertencia. En la práctica, si es igual que se llama con un objeto de una clase inesperada, es casi seguro que un error y desea a fallar rápido en los insectos.

Por ejemplo, si usted tiene un '' archivos ArrayList y llamar files.contains ( "MyFile.txt"), sería bueno si tienes un ClassCastException. En su lugar, Java simplemente devuelve falso, y es probable que tarda mucho tiempo hasta que se descubre que de insectos.

empiezo mis iguales (Object) implementaciones de esta manera:

if ((object == null) || !(object instaceof ThisClass)) {
    return false;
}

Esto también evitará que el aviso FindBugs pero no volverá automáticamente false cuando una subclase de ThisClass está siendo entregado. También podría considerarse iguales, sobre todo si su método equals(Object) no ha sido anulado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top