Подтвердить что ты не робот

Каковы способы сохранения hashCode/equals в соответствии с бизнес-определением класса?

Объект javadocs и Джош Блох рассказывают нам о том, как hashCode/equals должны быть реализованы, а хорошие IDE будут корректно обрабатывать поля разных типов. Некоторые обсуждения обо всем этом здесь.

Этот вопрос касается следующего шага: как вы убедитесь, что они остаются хорошими?

В частности, я считаю, что для большинства классов equals/hashCode должен быть реализован, как предлагает Bloch (и Eclipse и другая реализация IDE), и принять во внимание все не производные, бизнес-логические поля этого класса. Добавляя новые поля к классу как часть продолжающейся работы, люди часто забывают добавить их в реализацию equals/hashCode. Это может привести к труднодоступным ошибкам, когда два объекта кажутся равными, но на самом деле отличаются значением недавно введенного поля.

Как команда (даже одна!) поможет убедиться, что equals/hashCode в классе продолжает принимать во внимание все соответствующие поля, поскольку поля членов изменяются?

Я знаю, что Apache EqualsBuilder и HashCodeBuilder могут использовать отражение, которое, очевидно, потребуется для учета правильных полей, но я хочу избежать затрат на их использование. Существуют ли другие подходы к пометке полей, которые не включены в equals/hashCode, и должно быть? Анализ статического кода, функции IDE, методы unit test?

4b9b3361

Ответ 1

Потенциальный ответ, кажется, предлагается в этом вопросе.

Я не заглянул в Project Lombok, но я сразу подумал, hmm аннотации будут работать с генератором кода.

Ответ 3

Как насчет того, что вы пишете unittests для каждого класса, который хотите защитить. Модульные тесты должны

  • Используйте отражение, чтобы подсчитать количество полей и сравнить с локально сохраненными именами полей (и типами).
  • Если было обнаружено изменение количества полей (или типов полей), тогда вызывается hashcode. Если значение одно и то же, то сбой тестового примера. Оповести разработчика о том, что поля класса были изменены, и что разработчик должен: обновить equals и Hashcose и обновить unittest.
  • Убедитесь, что unittest работает в ночной сборке.

Ответ 4

Вам не нужно включать все поля в свой метод хэш-кода. Если вы использовали более одного поля в своем алгоритме хеш-кода, тогда шансы на него останутся хорошими. Сгенерированные IDE алгоритмы, которые я видел, используют случайное (во время выполнения, а не при выполнении) основное постоянное значение, поэтому просто убедитесь, что классы, которые могут оказаться в одной карте или дереве вместе (например, они реализуют одинаковые интерфейс) имеют разные постоянные значения. Если, конечно, вы не хотите равенства на уровне интерфейса.

Я никогда не видел, чтобы алгоритм хеш-кода "плохой" - вы беспокоитесь о непропорциональной сумме об этом.

Ответ 5

Похоже, что вы ищете аддон или функцию в среде IDE, которая выполняет анализ классов и генерирует предупреждения, если методы equals() и hashCode() не ссылаются на все соответствующие поля.

Это в основном переместило бы отражение накладных расходов в среду IDE, а не позволяло им иметь затраты во время выполнения.

К сожалению, я не знаю ни одного аддона, который делает это, хотя я обязательно посмотрю.

С другой стороны, как бы такой автоматизированный инструмент знал, какие поля имеют отношение к бизнес-логике? Вам, вероятно, нужно будет помечать ненужные поля чем-то вроде аннотации, иначе вы можете найти предупреждения, от которых вы не можете избавиться, но вы знаете, что они неверны.

Изменить: Этот ответ не полезен, поэтому я просто компилирую здесь полезные предложения из лучших ответов:

  • Проект Ломбок - приложение Eclipse, которое также работает со средствами сборки для обеспечения автоматической генерации equals(), hashCode() и других котельных табличек код - поскольку он сгенерирован во время компиляции, любые изменения в классе будут автоматически обновлять эти методы.
  • equalsverifier - предоставляет возможность автоматически unit test equals() с отражением - не поддерживает тестирование hashCode()

Ответ 6

Вы можете сериализовать свои объекты в строку, используя инструмент, который находит ваши свойства с помощью отражения (например, XStream) и сохраняет эту строку в репозитории. Ваши модульные тесты могут повторно сериализовать ваши объекты и сравнить результаты с вашими сохраненными значениями.

Как часть вашего собственного процесса, сделайте хранение этих строк зависящим от того, чтобы вручную подтвердить, что ваш хэш-код и равно правильно зафиксировать все соответствующие значения.