Можна ==
використовувати далі enum
?
Так: переписки мають жорсткі елементи керування екземплярами, що дозволяє використовувати ==
для порівняння екземплярів. Ось гарантія, надана мовною специфікацією (наголос від мене):
Тип enum не має інших випадків, ніж ті, які визначені його константами enum.
Це помилка часу компіляції для спроби явно інстанціювати тип enum. Цей final clone
метод Enum
забезпечує те, що enum
константи ніколи не можуть бути клоновані, а спеціальне звернення за допомогою механізму серіалізації забезпечує те, що повторювані екземпляри ніколи не створюються в результаті десеріалізації. Відображаюча інсталяція типів перерахувань заборонена. Ці чотири речі разом забезпечують відсутність екземплярів enum
типу, що перевищують enum
константи.
Оскільки існує лише один примірник кожної enum
константи, допустимо використовувати ==
оператор замість equals
методу при порівнянні двох посилань на об'єкти, якщо відомо, що принаймні одна з них відноситься до enum
константи . ( equals
Метод в Enum
- це final
метод, який просто викликає super.equals
свій аргумент і повертає результат, виконуючи таким чином порівняння ідентичності.)
Ця гарантія є достатньо сильною, що рекомендує Джош Блок: якщо ви наполягаєте на використанні однотонного шаблону, найкращим способом його реалізації є використання одноелемента enum
(див .: Ефективне Java 2-е видання, Пункт 3: Застосування властивості одиночного з допомогою приватний конструктор або тип 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
наступні:
- Це працює.
- Це швидше.
- Це безпечніше під час виконання.
- Це безпечніше під час компіляції.