Java getClass или instanceof для equals

Что лучше использовать для сравнения типов классов у переменных при написании equals? Я уже описывал этот метод в специальной статье. С одной стороны, я часто видел использование instanceof:

На первый взгляд, здесь всё впорядке. Но давайте создадим дочерний класс:

Вроде тоже ничего плохого. Но давайте проведём следующий эксперимент:

Результат будет такой:

Но в договорённости о работе equals в официальном JavaDoc сказано, что метод должен быть симметричным. Симметричность означает, что для каждой пары x и y у которой x.equals(y) должно быть равно y.equals(x). Значит, наши методы некорректны. Перепишем их на getClass:

Проведём эксперимент ещё раз:

Теперь класс может быть равен другому классу только если он строго того же типа, что и второй класс. Зато выполняется правило рефлексии для equals.

Вывод: Для equals всегда нужно сравнивать типы объектов через getClass.

Все методы equals и hashCode для данной статьи были сгенерированы с помощью плагина Jenerate для Eclipse.

Java getClass или instanceof для equals: 3 комментария

  1. А что, если наш объект — энтити хибернейт? getClass у такого объекта укажет нам на прокси и мы не сможем добраться до сравнения полей объекта.

    1. Ну да, возможно, для Hibernate это не всегда подходит, хотя и тоже спорно. Но требование по симметричности вообще было в самой документации от Oracle, поэтому я его здесь привёл.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *