Просто хотел мнения по этому поводу. Я всегда использовал флаги int, и мне просто было любопытно узнать о возможной простоте использования, если бы я использовал перечисления в Java?
Перечисления против флагов int?
Ответы (7)
Я очень сомневаюсь, что вы увидите преимущества производительности, а в некоторых случаях могут быть даже потери производительности, в зависимости от того, как вы их используете. Хотя я сомневаюсь, что они были бы значительными.
Преимущество заключается не в производительности, а в терминах или более четком выражении ваших намерений, что приводит к более читаемому (и безопасному типу) коду. Например, с целочисленными флагами ничто не будет жаловаться, если вы попытаетесь использовать (скажем) HTTP_STATUS_UNAUTHORIZED в качестве значения для вашего режима обмена файлами в вызове метода... тогда как, если бы оба они были перечислениями, параметр был бы строго типизирован как < em>на самом деле разрешить только режимы общего доступа к файлам (или нулевые, по общему признанию, при условии, что вы говорите о Java).
Как обычно, лучше всего об этом говорит Effective Java:
Программы, использующие шаблон перечисления
int
, ненадежны. Поскольку перечисленияint
являются константами времени компиляции, они компилируются в клиенты, которые их используют. Еслиint
, связанный с константой перечисления, изменен, его клиенты должны быть перекомпилированы. Если это не так, они все равно будут работать, но их поведение будет неопределенным.Не существует простого способа перевести константы перечисления
int
в печатные строки. Если вы напечатаете такую константу или отобразите ее из отладчика, все, что вы увидите, — это число, что не очень полезно. Не существует надежного способа перебрать все константы перечисленияint
в группе или даже получить размер группы перечисленияint
.
(+ еще 10 страниц о том, почему перечисления лучше :-))
Источник: Элемент 30. Использование перечисления вместо int
констант
Перечисления более четко выражают то, что вы пытаетесь сделать. Используйте их и не беспокойтесь о производительности; влияние на производительность будет незначительным.
Эквивалентом использования флагов битовой маски является использование EnumSet (который использует битовую маску).
enum Colour { RED, GREEN, BLUE }
Set<Colour> colours = EnumSet.noneOf(Colour.class);
colours.add(Colour.RED);
colours.add(Colour.GREEN);
if (colours.contains(Colour.RED)) // true
System.out.println(colours+" contains RED");
if (colours.contains(Colour.BLUE)) // false
По сути, это одно и то же, за исключением того, что перечисления самодокументированы. Я рекомендую использовать перечисления, как только кто-то еще может связаться с вашим кодом.
Тип Enum с собственными методами и оптимизированные контейнеры. Вы должны предпочесть его флагам int, потому что он безопаснее и, возможно, более эффективен (хотя я сомневаюсь, что в нем вообще много чего есть!).
В дополнение к безопасному коду у вас есть единственная ссылка для совместного использования коллекции (повторное использование).