Являются ли имена перечислений (enum) в Java интернированными?
Проблема: Интернирование имен enum в Java
Я хочу узнать, интернированы ли имена перечислений (enum) в Java. То есть, гарантируется ли, что выражение enum1.name() == enum2.name()
вернет true
, если имена двух перечислений совпадают?
Также интересует, безопасно ли сравнивать значение, возвращаемое методом enum.name()
, со строкой, которая гарантированно интернирована.
Заранее спасибо за помощь!
2 ответ(ов)
Хотя нет явной гарантии этого, конечный результат обязательно будет таким, что сравнение всегда будет успешным для констант enum
с одинаковыми именами:
enum A {enum1};
enum B {enum1};
System.out.println(A.enum1.name() == B.enum1.name()); // Выводит "true"
Причина этого заключается в том, что компилятор Java создает подклассы Enum
таким образом, что они в конечном итоге вызывают единственный защищённый конструктор Enum
, передавая ему имя значения enum
:
protected Enum(String name, int ordinal);
Имя встраивается в сгенерированный код в виде строкового литерала. Согласно документации по String
,
Все литеральные строки и выражения, имеющие строковые константы, интернируются.
Это является неявной гарантией того, что ваше выражение будет успешным, когда имена констант enum
совпадают. Однако я бы не полагался на это поведение и использовал equals(...)
вместо этого, так как любой, читающий мой код, будет ломать голову, думая, что я совершил ошибку.
В случае строк вам стоит использовать метод equals
для сравнения. Если говорить об этом, у вас уже есть перечисление (enum), которое можно сравнивать с помощью оператора равенства. В каких сценариях это может возникнуть?
Тем не менее, да, метод equals
вернёт true
, если строки одинаковы.
Что касается оператора равенства, не зная подробностей, могу сказать, что использовать его в данном случае – это не лучший подход в программировании.
Сравнение членов enum в Java: использовать == или equals()?
Цикл for для перебора enum в Java
Можно ли наследовать перечисления для добавления новых элементов?
Хорошая ли практика использовать порядковый номер enum?
Jackson: Сериализация и десериализация значений enum в виде целых чисел