Сравнение enum в Java: использовать == или equals()?
Краткий ответ: используйте ==
В Java для сравнения элементов enum всегда используйте оператор ==. Это безопасно, эффективно и является общепринятой практикой. Метод equals() тоже будет работать, но == предпочтительнее.
Почему это работает?
Каждое значение enum в Java — это синглтон. Виртуальная машина Java (JVM) гарантирует, что для каждого значения enum существует ровно один экземпляр объекта. Когда вы пишете Color.RED, JVM создаёт только один объект Color для этого значения, и все ссылки на Color.RED указывают на один и тот же объект в памяти.
Поэтому оператор ==, который сравнивает ссылки (адреса в памяти), всегда будет возвращать true для одинаковых enum-значений и false для разных. Это абсолютно надёжно.
Сравнение == и equals()
- Оператор == — сравнивает ссылки. Для enum это корректно, так как каждое значение — синглтон. Работает быстрее, так как не требует вызова метода.
- Метод equals() — в классе
Enumон переопределён и внутри также использует==(смотрит исходники:return this == other). То есть equals() делает то же самое, но с накладными расходами на вызов метода.
Пример, когда это важно
Рассмотрим ситуацию с null:
Color c1 = Color.RED;
Color c2 = null;
// Безопасно
if (c1 == c2) {
// false, без исключения
}
// Опасно — NullPointerException!
if (c2.equals(c1)) {
// Исключение!
}
При использовании == вы можете безопасно сравнивать с null. А вот equals() вызовет NullPointerException, если вызвать его на null-ссылке.
Использование в switch
Оператор == также используется внутри конструкции switch для enum:
Color color = Color.RED;
switch (color) {
case RED: // JVM использует == для сравнения
System.out.println("Красный");
break;
case GREEN:
System.out.println("Зелёный");
break;
}
Когда equals() всё же может пригодиться?
Технически, вы можете использовать equals(), особенно если ваш код работает с обобщёнными типами (generics) и вы не знаете точно, что сравниваете enum. Например:
public <T> boolean isDefault(T value, T defaultValue) {
return value.equals(defaultValue); // может быть опасно из-за null
}
Но даже в таких случаях лучше проверить на null или использовать Objects.equals().
Итоговая рекомендация
- Для сравнения enum используйте
==— это стандарт де-факто в Java-сообществе. - Это быстрее, безопаснее с
nullи делает код чище. equals()будет работать, но он избыточен и может привести к ошибкам.
Запомните правило: enum сравниваются через ==, строки — через equals().
<<Дополнение: equals() и Generics
Хотя == — лучший выбор для enum, есть один нюанс, когда equals() может быть более уместен. Это работа с обобщёнными типами (generics).
Представьте, что вы пишете универсальный метод, который принимает любые объекты, и вам нужно сравнить их с enum:
public <T> boolean checkValue(T value, T expected) {
// Если T — это enum, то == сработает, но компилятор не знает этого
return value == expected; // Ошибка компиляции, если T — не ссылочный тип?
}
На самом деле, в Java == работает для любых ссылочных типов, но если T может быть примитивом (например, int), то код не скомпилируется. В таких случаях безопаснее использовать Objects.equals():
public <T> boolean checkValue(T value, T expected) {
return Objects.equals(value, expected); // Устойчиво к null и работает с любыми типами
}
Objects.equals() внутри вызывает equals() для первого аргумента, предварительно проверив его на null. Для enum это будет работать корректно, хотя и с небольшими накладными расходами.
Однако в повседневном коде, когда вы точно знаете, что работаете с enum, используйте ==. Это идиоматичный и производительный подход.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги