Advertencia es igual a / hashCode en la anotación @Data lombok con herencia

103

Tengo una entidad que hereda de otra. Por otro lado, estoy usando el proyecto lombok para reducir el código repetitivo, así que puse una @Dataanotación. La anotación @Datacon herencia produce la siguiente advertencia:

Generando implementación equals / hashCode pero sin una llamada a superclase, aunque esta clase no extiende java.lang.Object. Si esto es intencional, agregue @EqualsAndHashCode(callSuper=false)a su tipo.

¿Es recomendable agregar anotación @EqualsAndHashCode (callSuper = true)o @EqualsAndHashCode (callSuper = false)? Si no se agrega, ¿cuál es callSuper=falseo callSuper=true?

Pau
fuente

Respuestas:

125

El valor predeterminado es false. Ese es el que obtiene si no lo especifica e ignora la advertencia.

Sí, se recomienda agregar una @EqualsAndHashCodeanotación en las @Dataclases anotadas que extiendan algo más que Object. No puedo decirle si lo necesita trueo false, eso depende de la jerarquía de su clase, y tendrá que examinarse caso por caso.

Sin embargo, para un proyecto o paquete, puede configurarlo lombok.configpara llamar a los súper métodos si no es una subclase directa de Object.

lombok.equalsAndHashCode.callSuper = call

Consulte la documentación del sistema de configuración sobre cómo funciona esto y la @EqualsEndHashCodedocumentación de las claves de configuración compatibles.

Divulgación: soy un desarrollador de lombok.

Roel Spilker
fuente
Trabajó para mi. Pero solo tenga en cuenta que para que el complemento delombok elija este archivo de configuración, debe ubicarse en el directorio raíz de origen de Java, no en el directorio de recursos, es decir, en src / main / java y no en src / main / resources
user577736
1
@Roel Me pregunto por qué el valor predeterminado es falso. Hubiera esperado lo contrario. Además, ¿hay una forma equivalente de hacer que toString () llame a super por defecto? Veo que puedo hacer "@ToString (callSuper = true)", pero no veo ningún ajuste de configuración. Gracias.
David Siegal
¿Importa si agrego @EqualsAndHashCode (callSuper = true) antes o después de @Data?
Anna Klein
@AnnaKlein el orden no importa
dan carter
47

@EqualsAndHashCode(callSuper=true) debería resolver la advertencia.

noscreenname
fuente
1
Esta debería ser la respuesta aceptada ya que no creo que la sugerencia de Roel deba hacerse "lombok.equalsAndHashCode.callSuper = call" en su lugar, se debería tomar una decisión para cada clase.
Anna Klein
4
@AnnaKlein No lo creo. De hecho, esta respuesta debería ser un comentario, no hay información nueva aquí, puedes encontrarla en mi pregunta. Sabía que @EqualsAndHashCoderesuelve la advertencia.
Pau
En realidad, según la respuesta aceptada (y mi respuesta a continuación), debe elegir entre 'callSuper = true' o 'callSuper = false' en la anotación.
Adam Wise
27

La principal pregunta original es:

¿Es aconsejable agregar la anotación @EqualsAndHashCode (callSuper = true) o @EqualsAndHashCode (callSuper = false)?

La respuesta aceptada es básicamente solo:

...eso depende...

Para ampliar eso, la documentación sobre @EqualsAndHashCode tiene una guía sólida sobre la cual elegir. Especialmente esto, en mi humilde opinión:

Al establecer callSuper en verdadero, puede incluir los métodos equals y hashCode de su superclase en los métodos generados. Para hashCode, el resultado de super.hashCode () se incluye en el algoritmo hash, y forequals, el método generado devolverá falso si la super implementación piensa que no es igual al objeto pasado. Tenga en cuenta que no todas las implementaciones iguales manejan esta situación correctamente. Sin embargo, las implementaciones de iguales generadas por lombok manejan esta situación correctamente, por lo que puede llamar de forma segura a su superclase igual si también tiene un método igual generado por lombok.

Para resumir un poco esto: Elija 'callSuper = true' si está heredando de una superclase que no tiene información de estado, o está usando la anotación @Data, o tiene implementaciones de equals / hash que "manejan la situación correctamente" - lo que interpreto que significa devolver un hash adecuado de los valores del estado.

Adam Wise
fuente
Creo que esta es la respuesta que explica bien cómo elegir entre callSuper = false y callSuper = true.
prageeth
10

Si también desea comparar los miembros de la superclase, utilice @EqualsAndHashCode(callSuper=true). Sin embargo, si solo desea comparar campos en la clase actual, puede usar @EqualsAndHashCode(callSuper=false)la opción predeterminada .

Si usa la función Delombok , puede ver que la diferencia es que cuando se establece en trueesta línea se agrega al método igual generado if (!super.equals(o)) return false;. Si tiene miembros en la superclase que deben tenerse en cuenta al comparar dos objetos, entonces debe establecerse en verdadero para comparar correctamente.

EvR2f
fuente