Tenemos una base de código OO, donde en mucho de los casos hashcode()
y equals()
simplemente no funcionan, sobre todo por la siguiente razón:Java: ¿forma limpia de lanzar automáticamente UnsupportedOperationException al llamar a hashCode() y equals()?
No hay manera de extender una clase instanciable y añadir una valor componente conservando el contrato igual a , a menos que esté dispuesto a renunciar a los beneficios de la abstracción orientada a objetos .
Eso es una cita de "Effective Java" por Joshua Bloch y hay más en ese tema en un gran artículo Artima aquí:
http://www.artima.com/lejava/articles/equality.html
y estamos perfectamente bien con eso, esto es no de qué se trata esta pregunta.
La pregunta es: se ve que es un hecho que en algunos casos no se puede satisfacer el contrato equals()
, lo que sería una forma limpia para hacer automáticamente hashcode()
y equals()
lanzar una UnsupportedOperationException?
¿Funcionaría una anotación? Estoy pensando en algo como @NotNull
: cada violación de contrato @NotNull
arroja una excepción automáticamente y usted no tiene nada más que hacer además de anotar sus parámetros/valor de retorno con @NotNull
.
Es conveniente, porque tiene 8 caracteres ("@NotNull") en lugar de repetir constantemente el mismo código de excepción de verificación/lanzamiento.
En el caso de que me preocupa, en cada aplicación, donde hashCode()/equals()
no tiene sentido, estamos repitiendo siempre lo mismo:
@Override
public int hashCode() {
throw new UnsupportedOperationException("contract violation: calling hashCode() on such an object makes no sense");
}
@Override
public boolean equals(Object o) {
throw new UnsupportedOperationException("contract violation: calling equals() on such an object makes no sense");
}
Sin embargo, esto es propenso a errores: es posible que por error se olvide cortar/pegar esto y puede ocasionar que los usuarios hagan un uso indebido de dichos objetos (digamos al tratar de ponerlos en las colecciones predeterminadas de Java).
O si la anotación no se puede hacer para crear este comportamiento, ¿funcionaría el AOP?
Curiosamente, el verdadero problema es la presencia de hashCode()
y equals()
en la parte superior de la jerarquía de Java que simplemente no tiene sentido en algunos casos. Pero entonces, ¿cómo lidiamos con este problema limpiamente?
+1 por negarse a implementar hashCode e igualar cuando no sea necesario, e incluso asegurarse de que no se puedan invocar emitiendo una excepción. Este es un cambio bienvenido al mantra que a menudo escuchas: lo primero que debes hacer es implementar esos dos métodos (y pensar mucho en ellos para que funcionen correctamente), incluso cuando la mayoría de los objetos nunca necesitan ninguno de los dos métodos. – Thilo
Un problema relacionado que tengo con los métodos autogenerados que Eclipse le brinda cuando escribe una nueva clase que implementa una interfaz es que todos se generan para 'return null',' return false', 'do nothing'. Me gustaría que el valor predeterminado sea 'throw UnsupportedOperationException (" TODO ")'. – Thilo
@Thilo Hago exactamente eso con mis plantillas de Eclipse, todos los cuerpos de métodos generados lanzan 'UnsupportedOperationException' –