Ostrzeżenie jest równe / hashCode w adnotacji @Data lombok z dziedziczeniem

108

Mam podmiot, który dziedziczy po innych. Z drugiej strony używam projektu lombok, aby zmniejszyć standardowy kod, więc umieściłem @Dataadnotację. Adnotacja @Dataz dziedziczeniem generuje następne ostrzeżenie:

Generowanie implementacji equals / hashCode, ale bez wywołania nadklasy, mimo że ta klasa nie rozszerza java.lang.Object. Jeśli jest to zamierzone, dodaj @EqualsAndHashCode(callSuper=false)do swojego typu.

Czy wskazane jest dodanie adnotacji, @EqualsAndHashCode (callSuper = true)czy @EqualsAndHashCode (callSuper = false)? Jeśli nie dodaje, Który z nich jest to callSuper=falseczy callSuper=true?

Pau
źródło

Odpowiedzi:

128

Wartość domyślna to false. To jest ten, który otrzymasz, jeśli go nie określisz i zignorujesz ostrzeżenie.

Tak, zaleca się dodanie @EqualsAndHashCodeadnotacji do @Dataklas z adnotacjami, które rozszerzają coś innego niż Object. Nie mogę ci powiedzieć, czy potrzebujesz, trueczy też false, to zależy od twojej hierarchii klas i będzie musiało zostać zbadane indywidualnie dla każdego przypadku.

Jednak w przypadku projektu lub pakietu można skonfigurować program in tak, lombok.configaby wywoływał super metody, jeśli nie jest to bezpośrednia podklasa Object.

lombok.equalsAndHashCode.callSuper = call

Zapoznaj się z dokumentacją systemu konfiguracji, aby dowiedzieć się, jak to działa, oraz @EqualsEndHashCodedokumentacją dotyczącą obsługiwanych kluczy konfiguracji.

Ujawnienie: jestem programistą lombok.

Roel Spilker
źródło
Pracował dla mnie. Pamiętaj jednak, że aby wtyczka delombok pobrała ten plik konfiguracyjny, powinien on być umieszczony w katalogu głównym źródła java, a nie w katalogu resources, tj. W src / main / java a nie w src / main / resources
user577736
1
@Roel Zastanawiam się, dlaczego wartość domyślna jest fałszywa. Spodziewałbym się czegoś przeciwnego. Czy istnieje równoważny sposób na to, aby metoda toString () wywoływała domyślnie super? Widzę, że mogę zrobić „@ToString (callSuper = true)”, ale nie widzę żadnego takiego ustawienia konfiguracji. Dzięki.
David Siegal
Czy to ma znaczenie, jeśli dodam @EqualsAndHashCode (callSuper = true) przed lub po @Data?
Anna Klein,
@AnnaKlein kolejność nie ma znaczenia
dan carter
48

@EqualsAndHashCode(callSuper=true) powinno rozwiązać ostrzeżenie.

noscreenname
źródło
1
To powinna być gotowa odpowiedź, ponieważ nie sądzę, aby sugestia Roela była wykonywana „lombok.equalsAndHashCode.callSuper = call” zamiast tego należy podjąć decyzję dla każdej klasy.
Anna Klein,
4
@AnnaKlein Nie sądzę. Właściwie ta odpowiedź powinna być komentarzem, nie ma tutaj żadnych nowych informacji, możesz to znaleźć w moim pytaniu. Wiedziałem, że @EqualsAndHashCoderozwiązuje ostrzeżenie.
Pau
Właściwie zgodnie z zaakceptowaną odpowiedzią (i moją odpowiedzią poniżej) powinieneś wybrać między „callSuper = true” lub „callSuper = false” w adnotacji.
Adam Wise
32

Główne pierwotne pytanie brzmi:

Czy warto dodać adnotację @EqualsAndHashCode (callSuper = true) lub @EqualsAndHashCode (callSuper = false)?

Przyjęta odpowiedź jest w zasadzie po prostu:

...to zależy...

Aby to rozwinąć, dokumentacja @EqualsAndHashCode zawiera solidne wskazówki dotyczące wyboru. Szczególnie to, IMHO:

Ustawiając callSuper na true, możesz uwzględnić metody equals i hashCode swojej nadklasy w generowanych metodach. W przypadku hashCode wynik super.hashCode () jest zawarty w algorytmie wyznaczania wartości skrótu, a znaki równościowe, wygenerowana metoda zwróci wartość false, jeśli super implementacja uzna, że ​​nie jest równy przekazanemu w obiekcie. Należy pamiętać, że nie wszystkie implementacje equals radzą sobie w tej sytuacji poprawnie. Jednak implementacje równań generowane przez lombok obsługują tę sytuację poprawnie, więc możesz bezpiecznie wywołać równość swojej nadklasy, jeśli ona również ma metodę równości wygenerowaną przez lombok.

Aby to nieco sprecyzować: wybierz opcję „callSuper = true”, jeśli dziedziczenie z nadklasy, która albo nie ma informacji o stanie, albo sama używa adnotacji @Data, albo ma implementacje równości / hash, które „prawidłowo radzą sobie z sytuacją” - co interpretuję jako zwracanie właściwego skrótu wartości stanu.

Adam Wise
źródło
Myślę, że to jest odpowiedź, która dobrze wyjaśnia, jak wybrać między callSuper = false i callSuper = true.
prageeth
Zgadzam się. To wyjaśnienie jest naprawdę pomocne.
Kira Resari
11

Jeśli chcesz porównać również członków nadklasy, użyj @EqualsAndHashCode(callSuper=true). Jeśli jednak tylko chcesz porównać pól w bieżącej klasy można użyć @EqualsAndHashCode(callSuper=false)która jest domyślną opcją.

Jeśli używasz funkcji Delombok, możesz zauważyć, że różnica polega na tym, że po ustawieniu truetej linii jest dodawany do wygenerowanej metody równościif (!super.equals(o)) return false; . Jeśli masz członków w nadklasie, które powinny być brane pod uwagę podczas porównywania dwóch obiektów, to aby porównać je poprawnie, musisz ustawić wartość true.

EvR2f
źródło