ejemplos - interfaz grafica java swing pdf
Advertencia de Findbugs: el método Equals no debería asumir nada sobre el tipo de su argumento (4)
Comienzo mis implementaciones equals (Object) de esta manera:
if ((object == null) || !(object instaceof ThisClass)) {
return false;
}
Esto también evitará la advertencia FindBugs pero no devolverá automáticamente false
cuando se entregue una subclase de ThisClass. También se puede considerar igual, especialmente si su método equals(Object)
no se ha anulado.
Cuando ejecuto FindBugs en mi proyecto, tengo algunas instancias del error descrito anteriormente.
Es decir, mis versiones principales de iguales arrojan el objeto RHS al mismo tipo que el objeto en el que se define la versión principal.
Sin embargo, no estoy seguro de si es posible un mejor diseño, ya que AFAIK Java no permite la variación en los parámetros del método, por lo que no es posible definir ningún otro tipo para el parámetro igual.
¿Estoy haciendo algo muy malo o los FindBugs están demasiado ansiosos?
Una forma diferente de expresar esta pregunta es: ¿cuál es el comportamiento correcto si el objeto pasado a igual no es del mismo tipo que un LHS? ¿Es falso o debería 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
}
Probablemente estés 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, estás asumiendo algo sobre el argumento de equals (): supones que es de tipo Foo. ¡Este no es el caso! También puede obtener un String (en cuyo caso, casi con certeza debe devolver false).
Entonces su código debería verse así:
public void equals(Object o) {
if (!(o instanceof Foo)) {
return false;
}
Foo other = (Foo) o;
// the real equals code
}
(o use el más estricto getClass() != o.getClass()
mencionado por Dave L.
También puedes verlo de esta manera:
Integer i = new Integer(42);
String s = "fourtytwo";
boolean b = i.equals(s);
¿Hay alguna razón por la cual este código arroje una ClassCastException
lugar de terminar normalmente y establecer b
en false
?
Lanzar una ClassCastException
como respuesta a .equals()
no sería sensato. Porque incluso si es una pregunta estúpida ("¡Por supuesto que una Cadena nunca es igual a un Foo!"), Sigue siendo válida con una respuesta perfectamente correcta ("no" == false
).
Recomiendo ignorar dicha advertencia de Findbugs. En la práctica, si se llama a igual con un objeto de una clase inesperada, es casi seguro que se trata de un error y desea fallar rápidamente en los errores.
Por ejemplo, si tiene un ''ArrayList files'' y call files.contains ("MyFile.txt"), sería bueno que obtuviera una ClassCastException. En cambio, Java simplemente devuelve falso, y es probable que demore un tiempo hasta que descubras ese error.
Normalmente, al implementar Equals puede verificar si la clase del argumento es igual (o compatible) a la clase implementadora antes de enviarla. Algo como esto:
if (getClass() != obj.getClass())
return false;
MyObj myObj = (MyObj) obj;
Si lo hace de esta manera evitará la advertencia FindBugs.
Una nota al margen para dirigir un comentario:
Algunas personas discuten usar instanceof
lugar de getClass
para verificar el tipo de seguridad. Hay un gran debate al respecto, en el que traté de no entrar cuando noté que se puede verificar la igualdad de clases o la compatibilidad, pero creo que no puedo evitarlo. Todo se reduce a esto: si usas instanceof
, puedes soportar la igualdad entre las instancias de una clase y las instancias de su subclase, pero te arriesgas a romper el contrato simétrico de equals
. En general, recomendaría no utilizar instanceof
menos que sepa que lo necesita y que sepa lo que está haciendo. Para más información, ver:
- http://www.artima.com/weblogs/viewpost.jsp?thread=4744
- ¿Qué problemas se deben tener en cuenta al anular equals y hashCode en Java?
- http://www.macchiato.com/columns/Durable5.html
- http://commons.apache.org/lang/api-release/org/apache/commons/lang/builder/EqualsBuilder.html (ayudante de implementación de Apache common)
- http://www.eclipsezone.com/eclipse/forums/t92613.rhtml (el valor predeterminado de Eclipse es el generador)
- El generador de NetBeans también usa getClass ()