Предупреждение равно / hashCode в аннотации @Data lombok с наследованием

104

У меня есть сущность, которая наследуется от других. С другой стороны, я использую проект 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документацию по поддерживаемым ключам конфигурации.

Раскрытие информации: я разработчик ломбока.

Рул Спилкер
источник
Работал у меня. Но просто имейте в виду, что для того, чтобы плагин delombok выбрал этот файл конфигурации, он должен быть помещен в корневой каталог исходного кода java, а не в каталог ресурсов, то есть в src / main / java, а не в src / main / resources
user577736
1
@Roel Мне интересно, почему по умолчанию - false. Я ожидал обратного. Кроме того, есть ли эквивалентный способ заставить toString () вызывать super по умолчанию? Я вижу, что могу выполнить «@ToString (callSuper = true)», но не вижу такой настройки конфигурации. Спасибо.
Дэвид Сигал
Имеет ли значение, добавляю ли я @EqualsAndHashCode (callSuper = true) до или после @Data?
Анна Кляйн
@AnnaKlein порядок не имеет значения
дан извозчика
47

@EqualsAndHashCode(callSuper=true) должно устранить предупреждение.

без имени
источник
1
Это должен быть принятый ответ, поскольку я не думаю, что предложение Роэла должно выполняться «lombok.equalsAndHashCode.callSuper = call», вместо этого следует принимать решение для каждого класса.
Анна Кляйн
4
@AnnaKlein Я так не думаю. Фактически, этот ответ должен быть комментарием, здесь нет новой информации, вы можете найти это в моем вопросе. Я действительно знал, @EqualsAndHashCodeчто это предупреждение устраняет.
Pau
На самом деле в соответствии с принятым ответом (и моим ответом ниже) вы должны выбрать в аннотации «callSuper = true» или «callSuper = false».
Адам Уайз
27

Главный исходный вопрос:

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

Принятый ответ в основном просто:

...это зависит от...

Чтобы расширить это, в документации по @EqualsAndHashCode есть некоторые четкие рекомендации по выбору. Особенно это, ИМХО:

Установив для callSuper значение true, вы можете включить методы equals и hashCode вашего суперкласса в сгенерированные методы. Для hashCode результат super.hashCode () включается в алгоритм хеширования, а для forequals сгенерированный метод вернет false, если супер реализация считает, что он не равен переданному объекту. Имейте в виду, что не все реализации equals справляются с этой ситуацией должным образом. Однако сгенерированные ломбоком реализации equals справляются с этой ситуацией должным образом, поэтому вы можете безопасно вызывать свой суперкласс equals, если он также имеет сгенерированный ломбоком метод equals.

Чтобы немного уменьшить это: выберите callSuper = true, если вы наследуете суперкласс, который либо не имеет информации о состоянии, либо сам использует аннотацию @Data, либо имеет реализации equals / hash, которые «обрабатывают ситуацию должным образом» - что я интерпретирую как возвращение правильного хеша значений состояния.

Адам Уайз
источник
Я думаю, что это ответ, который хорошо объясняет, как выбирать между callSuper = false и callSuper = true.
прагит
10

Если вы хотите сравнить также члены суперкласса, используйте @EqualsAndHashCode(callSuper=true). Однако, если вы хотите сравнить поля только в текущем классе, вы можете использовать параметр @EqualsAndHashCode(callSuper=false)по умолчанию .

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

EvR2f
источник