Як краще порівнювати перераховувані типи в Java?


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

Нещодавно на Stack Overflow я наштовхнувся на, здавалося б, просте запитання: “Що краще використати для порівняння enum ‘ів – == чи equals ()?”. Ви, звичайно, можете відповісти, що жодної різниці немає, але будете не праві, бо у відповідях на це запитання було наведено багато цікавих аргументів на користь обох варіантів. 

Вони ж обидва працюють, правда?

Так. Як написано у документації, “допустимо використати оператор == замість методу equals, якщо напевно відомо, що хоча б один з них посилається на перераховуваний тип” (“it is permissible to use the == operator in place of the equals method when comparing two object references if it is known that at least one of them refers to an enum constant”). Причина цього дуже проста: кожен з об’єктів enum ‘а створюється тільки один раз, і тому, якщо Ви створите десять змінних рівних SomeEnum.RED, вони всі посилатимуться на той самий об’єкт (а оператор == саме це і перевіряє).

Які  переваги є в оператора ==?

  • Він ніколи не викине NullPointerException:
    enum Color { BLACK, WHITE };Color nothing = null;if (nothing == Color.BLACK); // Усе отличноif (nothing.equals (Color.BLACK)); // викидає NullPointerException
  • В одній з відповідей наводилася цитата Джошуа Блоха (автор книги “Effective Java”; мабуть, і цитата звідти) про те, що цей оператор працює швидше, і якщо гарантується унікальність кожного екземпляра класу, то варто використати саме його.
  • Як відомо, порівняння через == перевіряються на відповідності типів під час компіляції (це добре, оскільки допоможе вчасно виявити помилку):
    enum Color { BLACK, WHITE };enum Chiral { LEFT, RIGHT };if (Color.BLACK.equals (Chiral.LEFT)); // Компилируетсяif (Color.BLACK == Chiral.LEFT); // НЕ КОМПІЛЮЄТЬСЯ!!! Несумісні типи!
  • Цей варіант коротший, і відразу зрозуміло, що відбувається саме перевірка рівності (тобто варіант більше читаний).

Як серйозно всі підійшли до запитання! Ну тепер точно використовуватиму оператор рівності

Не поспішайте так. Не всі одноголосно “за” ==. Ось що пишуть прибічники equals ():

  • Немає жодного випадку, коли змінна перераховуваного типу дорівнювала null – якщо Ви так описуєте якийсь особливий стан, то його можна просто замінити на ще один допустимий стан enum ‘а. NPE не потрібно приховувати, оскільки це, найімовірніше, помилка, і чим раніше про неї стане відомо, тим краще.
  • Аргумент про швидкість == дуже сумнівний. Сучасні компілятори, швидше за все вміють замінювати equals на == самостійно. Якщо це не так (як довели пізніше, що це, дійсно, не так), то це проблема Java, над якою треба працювати.
  • Який Java-програміст не знає, що робить equals? Такий варіант навпаки більше читаний, оскільки для об’єктів ми звикли використовувати саме метод equals. Отже, і для enum ‘ів треба чинити так само, щоб не виникало плутанини.

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *