Можна ==використовувати далі 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наступні:
- Це працює.
- Це швидше.
- Це безпечніше під час виконання.
- Це безпечніше під час компіляції.