Может ==
быть использован на enum
?
Да: перечисления имеют жесткие элементы управления экземплярами, что позволяет использовать их ==
для сравнения. Вот гарантия, предоставляемая спецификацией языка (выделено мной):
Тип enum не имеет экземпляров, отличных от определенных его константами.
Это ошибка времени компиляции, чтобы попытаться явно создать экземпляр типа enum. final clone
Метод Enum
гарантирует , что enum
константы никогда не могут быть клонированы, а специальная обработка с помощью механизма сериализации гарантирует , что дублирующие экземпляры никогда не созданные в результате десериализации. Рефлексивная реализация типов перечислений запрещена. Вместе эти четыре вещи гарантируют, что экземпляры enum
типа не существуют вне тех, которые определены enum
константами.
Поскольку существует только один экземпляр каждой enum
константы, допустимо использовать ==
оператор вместо equals
метода при сравнении двух ссылок на объекты, если известно, что хотя бы одна из них ссылается на enum
константу . ( equals
Метод in Enum
- это final
метод, который просто вызывает super.equals
свой аргумент и возвращает результат, тем самым выполняя сравнение идентификаторов.)
Эта гарантия достаточно сильна, и Джош Блох рекомендует, что, если вы настаиваете на использовании одноэлементного шаблона, лучший способ реализовать его - это использовать одноэлементный enum
(см. Effective Java 2nd Edition, Item 3: Enforment свойство 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
:
- Оно работает.
- Это быстрее
- Это безопаснее во время выполнения.
- Это безопаснее во время компиляции.