Может ли ==
использоваться на enum
?
Да: перечисления имеют строгие элементы управления экземплярами, что позволяет использовать ==
для сравнения экземпляров. Вот гарантия, предоставленная языковой спецификацией (выделено мной):
Тип enum не имеет экземпляров, отличных от определенных его константами.
Ошибка времени компиляции - попытка явно создать экземпляр типа enum. Метод final clone
в Enum
гарантирует, что константы enum
никогда не могут быть клонированы, а специальная обработка механизмом сериализации гарантирует, что повторяющиеся экземпляры никогда не будут созданы в результате десериализации. Рефлексивная реализация типов перечислений запрещена. Вместе эти четыре вещи гарантируют, что экземпляров типа enum
не существует, кроме тех, которые определены константами enum
.
Поскольку существует только один экземпляр каждой enum
константы, допустимо использовать оператор ==
вместо метода equals
при сравнении двух ссылок на объекты, если известно, что хотя бы один из них относится к enum
константе . (Метод equals
в Enum
- это метод final
, который просто вызывает super.equals
своего аргумента и возвращает результат, таким образом выполняя сравнение идентификаторов.)
Эта гарантия достаточно сильна, и Джош Блох рекомендует, что, если вы настаиваете на использовании одноэлементного шаблона, лучший способ реализовать его - использовать одноэлементный enum
(см .: Effective Java 2nd Edition, Правило 3: принудительное использование свойства singleton с помощью частного конструктора или типа enum ; также Безопасность потоков в Singleton )
В чем различия между ==
и equals
?
В качестве напоминания следует сказать, что, как правило, ==
НЕ является жизнеспособной альтернативой equals
. Однако, когда это так (например, с enum
), необходимо учитывать два важных различия:
==
никогда не бросает NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
подлежит проверке совместимости типов во время компиляции
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
Должно ли ==
использоваться, когда это применимо?
Блох особо отмечает, что неизменяемые классы, которые имеют надлежащий контроль над своими экземплярами, могут гарантировать своим клиентам, что ==
пригоден для использования. enum
специально упоминается в качестве примера.
Пункт 1: Рассмотрим статические фабричные методы вместо конструкторов
[...] позволяет неизменному классу гарантировать, что не существует двух одинаковых экземпляров: a.equals(b)
тогда и только тогда, когда a==b
. Если класс дает такую гарантию, его клиенты могут использовать оператор ==
вместо метода equals(Object)
, что может привести к повышению производительности. Типы enum предоставляют эту гарантию.
Подводя итог, аргументы для использования ==
на enum
:
- Работает.
- Это быстрее.
- Во время выполнения безопаснее.
- Безопаснее во время компиляции.