После прочтения (опять же, должно было сделать это давным-давно) реализация equals и hashcode правильно, я пришел к этим выводам, который работает для меня:
Если pre JDK 7: Предпочитаете использовать утилиту apalsbuild и hashcodebuilder. (или Гуава). Их javadocs содержит примеры того, как их использовать в хорошем смысле.
Если JDK 7 ++: используйте класс служебных объектов
Но, если вы пишете для hibernate, появятся некоторые специальные реквизиты (см. источники дальше) Среди них рекомендуемое использование instanceof вместо getClass, из-за спящего режима, создающего прокси подклассов, которые ленивы загружены.
Но, как я понимаю, если это происходит, возникает другая потенциальная проблема: причина использования getClass заключается в обеспечении симметричного свойства равноценного контракта. JavaDocs:
*It is symmetric: for any non-null reference values x and y, x.equals(y)
should return true if and only if y.equals(x) returns true.*
И используя instanceof, можно не быть симметричным. Пример: B расширяет A. A equals выполняет проверку экземпляра A. B equals выполняет экземпляр проверки B. Дайте A a и B b:
a.equals(b) → true b.equals(a) → false
Как реализовать equals с hibernate, не рискуя потерять симметричное свойство? Кажется, я не безопасен при использовании getClass, и я не безопасен при использовании экземпляра?
Является ли ответ никогда не добавлять значительных членов в подклассы, а затем быть безопасным в использовании instanceof (для спящего режима, который есть)?
Источники, которые я читал:
Какие проблемы следует учитывать при переопределении equals и hashCode в Java?
Пункты 7 и 8 в Джош Блохсе отличная книга "Эффективная Java", http://web.archive.org/web/20110622072109/http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
О Java 7: http://www.javacodegeeks.com/2012/11/guavas-objects-class-equals-hashcode-and-tostring.html