Warnung gleich / hashCode auf @Data Annotation Lombok mit Vererbung

96

Ich habe eine Entität, die von anderen erbt. Auf der anderen Seite verwende ich das Lombok-Projekt, um den Boilerplate-Code zu reduzieren, also füge ich @DataAnmerkungen hinzu. Die Annotation @Datamit Vererbung erzeugt die nächste Warnung:

Generieren der Implementierung von equals / hashCode, jedoch ohne Aufruf der Oberklasse, obwohl diese Klasse java.lang.Object nicht erweitert. Wenn dies beabsichtigt ist, fügen Sie @EqualsAndHashCode(callSuper=false)es Ihrem Typ hinzu.

Ist es ratsam, Anmerkungen hinzuzufügen @EqualsAndHashCode (callSuper = true)oder @EqualsAndHashCode (callSuper = false)? Wenn es nicht hinzugefügt wird, welches ist es callSuper=falseoder callSuper=true?

Pau
quelle

Antworten:

119

Der Standardwert ist false. Dies ist diejenige, die Sie erhalten, wenn Sie sie nicht angeben und die Warnung ignorieren.

Ja, es wird empfohlen, eine @EqualsAndHashCodeAnnotation zu den @Dataannotierten Klassen hinzuzufügen , die etwas anderes als Object erweitern. Ich kann Ihnen nicht sagen, ob Sie dies benötigen trueoder false, dies hängt von Ihrer Klassenhierarchie ab und muss von Fall zu Fall geprüft werden.

Für ein Projekt oder Paket können Sie jedoch konfigurieren, dass die Supermethoden lombok.configaufgerufen werden, wenn es sich nicht um eine direkte Unterklasse von Object handelt.

lombok.equalsAndHashCode.callSuper = call

Informationen dazu finden Sie in der Dokumentation zum Konfigurationssystem sowie in der @EqualsEndHashCodeDokumentation zu den unterstützten Konfigurationsschlüsseln.

Offenlegung: Ich bin ein Lombok-Entwickler.

Roel Spilker
quelle
Hat für mich gearbeitet. Beachten Sie jedoch, dass das Delombok-Plugin diese Konfigurationsdatei im Java-Quellstammverzeichnis ablegen sollte, nicht im Ressourcenverzeichnis, dh in src / main / java und nicht in src / main / resources
user577736
1
@Roel Ich frage mich, warum der Standardwert falsch ist. Ich hätte das Gegenteil erwartet. Gibt es auch eine äquivalente Möglichkeit, toString () dazu zu bringen, standardmäßig Super aufzurufen? Ich sehe, dass ich "@ToString (callSuper = true)" ausführen kann, aber keine solche Konfigurationseinstellung sehe. Vielen Dank.
David Siegal
Ist es wichtig, ob ich @EqualsAndHashCode (callSuper = true) vor oder nach @Data hinzufüge?
MichaelB
@AnnaKlein die Reihenfolge spielt keine Rolle
Dan Carter
46

@EqualsAndHashCode(callSuper=true) sollte die Warnung beheben.

noscreenname
quelle
1
Dies sollte die Antwort sein, da ich nicht denke, dass der Vorschlag von Roel "lombok.equalsAndHashCode.callSuper = call" gemacht werden sollte, stattdessen sollte eine Entscheidung für jede Klasse getroffen werden.
MichaelB
3
@AnnaKlein Das glaube ich nicht. In der Tat sollte diese Antwort ein Kommentar sein, es gibt hier keine neuen Informationen, das finden Sie in meiner Frage. Ich wusste, dass @EqualsAndHashCodedie Warnung behoben wird.
Pau
Tatsächlich sollten Sie gemäß der akzeptierten Antwort (und meiner Antwort unten) in der Anmerkung zwischen 'callSuper = true' oder 'callSuper = false' wählen.
Adam Wise
20

Die ursprüngliche Hauptfrage lautet:

Ist es ratsam, die Annotation @EqualsAndHashCode (callSuper = true) oder @EqualsAndHashCode (callSuper = false) hinzuzufügen?

Die akzeptierte Antwort lautet im Grunde nur:

...kommt darauf an...

Um dies zu erweitern, enthält die Dokumentation zu @EqualsAndHashCode eine solide Anleitung zur Auswahl. Besonders das, IMHO:

Indem Sie callSuper auf true setzen, können Sie die Methoden equals und hashCode Ihrer Oberklasse in die generierten Methoden aufnehmen. Für hashCode ist das Ergebnis von super.hashCode () im Hash-Algorithmus enthalten, und bei Forequals gibt die generierte Methode false zurück, wenn die Super-Implementierung der Ansicht ist, dass es nicht dem übergebenen Objekt entspricht. Beachten Sie, dass nicht alle gleichwertigen Implementierungen mit dieser Situation richtig umgehen. Von Lombok generierte Gleichheitsimplementierungen behandeln diese Situation jedoch ordnungsgemäß, sodass Sie Ihre Superklasse sicher als gleichwertig bezeichnen können, wenn auch sie über eine von Lombok generierte Gleichheitsmethode verfügt.

Um dies ein wenig zu reduzieren: Wählen Sie 'callSuper = true', wenn Sie von einer Oberklasse erben, die entweder keine Statusinformationen enthält oder selbst die Annotation @Data verwendet oder Implementierungen von equals / hash verwendet, die "die Situation richtig handhaben". - was ich so interpretiere, dass ein korrekter Hash der Zustandswerte zurückgegeben wird.

Adam Wise
quelle
Ich denke, dies ist die Antwort, die gut erklärt, wie man zwischen callSuper = false und callSuper = true wählt.
Prageeth
5

Wenn Sie auch die Mitglieder der Oberklasse vergleichen möchten, verwenden Sie @EqualsAndHashCode(callSuper=true). Wenn Sie jedoch nur Felder in der aktuellen Klasse vergleichen möchten, können Sie diese verwenden. @EqualsAndHashCode(callSuper=false)Dies ist die Standardoption .

Wenn Sie die Verwendung Delombok -Feature können Sie sehen , dass der Unterschied , dass, wenn zu setzen truediese Linie wird auf die erzeugte hinzugefügt equals Methode if (!super.equals(o)) return false;. Wenn Sie Mitglieder in der Oberklasse haben, die beim Vergleich zweier Objekte berücksichtigt werden sollten, muss sie auf true gesetzt werden, um einen korrekten Vergleich zu ermöglichen.

EvR2f
quelle