gui framework definicion java equals

framework - set border java



¿Por qué el área#de Java es igual al método que no reemplaza a Object#es igual? (2)

"¿Por qué el área # de Java es igual al método que no reemplaza al objeto # que es igual a"?

Debido a que la anulación no es necesaria para los métodos sobrecargados en los que los parámetros son de diferentes tipos.

Un método anulado tendría exactamente el mismo nombre de método, tipo de retorno, número de parámetros y tipos de parámetros que el método en la clase principal, y la única diferencia sería la definición del método.

Este caso no nos obliga a anular pero está sobrecargando, ya que sigue estas reglas:

1.) El número de parámetros es diferente para los métodos.

2.) Los tipos de parámetros son diferentes (como cambiar un parámetro que era un flotante a un int).

"¿Por qué no solo nombraron el método cuestionable de una manera que no choca con un concepto tan fundamental como el método de iguales?"

Porque esto podría hacer tropezar a la gente en el futuro. Si tuviéramos una máquina del tiempo hasta los 90, podríamos hacerlo sin preocuparnos.

Acabo de encontrar un problema causado por el método java.awt.geom.Area#equals(Area) Java java.awt.geom.Area#equals(Area) . El problema se puede simplificar a la siguiente prueba unitaria:

@org.junit.Test public void testEquals() { java.awt.geom.Area a = new java.awt.geom.Area(); java.awt.geom.Area b = new java.awt.geom.Area(); assertTrue(a.equals(b)); // -> true java.lang.Object o = b; assertTrue(a.equals(o)); // -> false }

Después de rascar y depurar la cabeza, finalmente vi en la fuente de JDK, que la firma del método equals en el Area ve así:

public boolean equals(Area other)

Tenga en cuenta que @Override el método normal equals de Object , pero en su lugar solo sobrecarga el método con un tipo más concreto. Por lo tanto, las dos llamadas en el ejemplo anterior terminan llamando a diferentes implementaciones de equals .

Como este comportamiento ha estado presente desde Java 1.2, asumo que no se considera un error. Por lo tanto, estoy más interesado en descubrir por qué se tomó la decisión de no anular correctamente el método de equals , pero al mismo tiempo proporcionar una variante sobrecargada. (Otra sugerencia de que esta fue una decisión real tomada es la ausencia de un método hashCode() sobrescrito hashCode() .

Mi única conjetura sería que los autores temen que la implementación lenta de las áreas sea inadecuada para comparar la igualdad al colocar Area s en Set , Map , etc. estructuras de datos. (En el ejemplo anterior, podría agregar a a HashSet , y aunque b es igual a a , la llamada contains(b) fallará). De nuevo, ¿por qué no solo nombraron el método cuestionable de una manera que no choca? ¿Con un concepto tan fundamental como el método de equals ?


RealSkeptic vinculado a JDK-4391558 en un comentario anterior. El comment en ese error explica el razonamiento:

El problema con la anulación de equals (Object) es que también debe anular hashCode () para devolver un valor que garantice que equals () sea verdadero solo si los hashcodes de los dos objetos también son iguales.

pero:

El problema aquí es que Area.equals (Área) no realiza una comparación muy directa. Examina minuciosamente todas y cada una de las piezas de geometría en las dos Áreas y comprueba si cubren los mismos espacios cerrados. Dos objetos del Área podrían tener una descripción completamente diferente del mismo espacio cerrado e iguales (Área) detectarían que eran iguales.

Básicamente, nos quedamos con una serie de opciones no tan agradables, como:

deprecate equals (Área) y cree un nombre alternativo para esa operación, como "areasEqual" para evitar la confusión. Desafortunadamente, el método antiguo se mantendría y sería vinculable y atraparía a muchas personas que tenían la intención de invocar la versión de iguales (objeto).

o:

deprecate equals (Area) y cambia su implementación para que sea exactamente igual a igual a (Object) para evitar problemas semánticos si se llama al método incorrecto. Cree un nuevo método con un nombre diferente para evitar confusiones para implementar la funcionalidad antigua proporcionada por equals (Área).

o:

implementar es igual a (Objeto) para llamar a igual (Área) e implementar un código de hash ficticio () que respeta el contrato de igual / hashCode de forma degenerada devolviendo una constante. Esto haría al método hashCode esencialmente inútil y haría que los objetos del Área sean casi inútiles como claves en un HashMap o Hashtable.

u otras formas de modificar el comportamiento de los equals(Area) que cambiaría su semántica o lo haría inconsistente con el hashCode .

Parece que los mantenedores consideran que cambiar este método no es factible (porque ninguna de las opciones descritas en el comentario de error resuelve el problema) ni importante (ya que el método, tal como se implementó, es bastante lento y probablemente solo se volvería verdadero cuando se compara) una instancia de un Area consigo misma, como sugiere el comentarista).