Попередження дорівнює / hashCode на анотації @Data lombok із успадкуванням


105

У мене є сутність, яка успадковує від інших. З іншого боку, я використовую проект lombok для зменшення типового коду, тому ставлю @Dataанотацію. Анотація @Dataз успадкуванням видає наступне попередження:

Створення реалізації equals / hashCode, але без виклику суперкласу, хоча цей клас не поширює java.lang.Object. Якщо це навмисно, додайте @EqualsAndHashCode(callSuper=false)до свого типу.

Чи доцільно додавати анотацію @EqualsAndHashCode (callSuper = true)чи @EqualsAndHashCode (callSuper = false)? Якщо його не додано, то який це callSuper=falseчи callSuper=true?

Відповіді:


125

Значення по замовчуванням є false. Це той, який ви отримаєте, якщо не вкажете його та проігноруєте попередження.

Так, рекомендується додати @EqualsAndHashCodeанотацію до @Dataанотованих класів, які розширюють щось інше, ніж Object. Я не можу сказати вам, чи потрібно вам це, trueабо falseце залежить від вашої ієрархії класів, і потрібно буде перевіряти їх у кожному конкретному випадку.

Однак для проекту або пакету ви можете налаштувати lombok.configвиклик супер методів, якщо це не прямий підклас Object.

lombok.equalsAndHashCode.callSuper = call

Дивіться документацію по системі конфігурації , як це працює, і @EqualsEndHashCodeдокументацію для підтримуваних ключів конфігурації.

Розкриття інформації: Я розробник lombok.


Працював у мене. Але просто майте на увазі, що для того, щоб плагін delombok вибрав цей конфігураційний файл, він повинен бути розміщений у кореневому каталозі Java, а не в каталозі ресурсів, тобто в src / main / java і не в src / main / resources
user577736

1
@Roel Мені цікаво, чому за замовчуванням значення false. Я б очікував протилежного. Крім того, чи існує еквівалентний спосіб отримати toString () для виклику супер за замовчуванням? Я бачу, що можу зробити "@ToString (callSuper = true)", але не бачу жодного такого налаштування конфігурації. Дякую.
Девід Сігал,

Чи має значення, якщо я додаю @EqualsAndHashCode (callSuper = true) до або після @Data?
Anna Klein

@AnnaKlein порядок не має значення
dan

47

@EqualsAndHashCode(callSuper=true) має вирішити попередження.


1
Це має бути прийнятою відповіддю, оскільки я не думаю, що пропозицію Роеля слід робити "lombok.equalsAndHashCode.callSuper = call", замість цього для кожного класу повинно бути прийнято рішення.
Anna Klein

4
@AnnaKlein Я не думаю. Насправді ця відповідь має бути коментарем, тут немає нової інформації, це можна знайти в моєму запитанні. Я знав, що @EqualsAndHashCodeвирішує попередження.
Пау

Насправді, згідно прийнятої відповіді (і моєї відповіді нижче), ви повинні вибрати між "callSuper = true" або "callSuper = false" в анотації.
Адам Мудрий

28

Основне оригінальне питання:

Чи доцільно додавати анотацію @EqualsAndHashCode (callSuper = true) або @EqualsAndHashCode (callSuper = false)?

Прийнята відповідь в основному просто:

...це залежить...

Щоб розширити це, у документації на @EqualsAndHashCode є кілька вагомих вказівок щодо вибору. Особливо це, ІМХО:

Встановивши для callSuper значення true, ви можете включити в згенеровані методи методи equals і hashCode вашого суперкласу. Для hashCode результат super.hashCode () включається в алгоритм хешування, і forequals, згенерований метод поверне false, якщо супер реалізація вважає, що він не дорівнює переданому в об'єкті. Майте на увазі, що не всі рівні реалізації правильно обробляють цю ситуацію. Однак реалізації згенерованих lombok рівних дійсно обробляють цю ситуацію належним чином, тому ви можете сміливо назвати свій суперклас рівними, якщо він теж має метод рівних генерованого ломбоком.

Щоб трохи перегнати це: Виберіть 'callSuper = true', якщо ви успадковуєте суперклас, який або не має інформації про стан, або сам використовує анотацію @Data, або має реалізації equals / hash, які "правильно обробляють ситуацію" - що я трактую як означає повернення належного хешу державних цінностей.


Я думаю, що це відповідь, яка добре пояснює, як вибрати між callSuper = false і callSuper = true.
prageeth

10

Якщо ви хочете порівняти і членів суперкласу, тоді використовуйте @EqualsAndHashCode(callSuper=true). Однак, якщо ви хочете порівняти лише поля поточного класу, ви можете використовувати @EqualsAndHashCode(callSuper=false)цей варіант, який є типовим .

Якщо ви використовуєте функцію Delombok, ви можете побачити, що різниця полягає в тому, що при встановленні на trueцей рядок додається метод згенерованих рівнихif (!super.equals(o)) return false; . Якщо у вас є члени суперкласу, які слід брати до уваги при порівнянні двох об’єктів, то для правильного порівняння йому потрібно встановити значення true.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.