Перечисления против флагов int?

Просто хотел мнения по этому поводу. Я всегда использовал флаги int, и мне просто было любопытно узнать о возможной простоте использования, если бы я использовал перечисления в Java?


person ahodder    schedule 24.02.2011    source источник
comment
О каком языке вы говорите? Например, в C# это одно и то же.   -  person Kirk Woll    schedule 24.02.2011


Ответы (7)


Я очень сомневаюсь, что вы увидите преимущества производительности, а в некоторых случаях могут быть даже потери производительности, в зависимости от того, как вы их используете. Хотя я сомневаюсь, что они были бы значительными.

Преимущество заключается не в производительности, а в терминах или более четком выражении ваших намерений, что приводит к более читаемому (и безопасному типу) коду. Например, с целочисленными флагами ничто не будет жаловаться, если вы попытаетесь использовать (скажем) HTTP_STATUS_UNAUTHORIZED в качестве значения для вашего режима обмена файлами в вызове метода... тогда как, если бы оба они были перечислениями, параметр был бы строго типизирован как < em>на самом деле разрешить только режимы общего доступа к файлам (или нулевые, по общему признанию, при условии, что вы говорите о Java).

person Jon Skeet    schedule 24.02.2011
comment
Спасибо за ваш ответ; и отметил. - person ahodder; 24.02.2011

Как обычно, лучше всего об этом говорит Effective Java:

Программы, использующие шаблон перечисления int, ненадежны. Поскольку перечисления int являются константами времени компиляции, они компилируются в клиенты, которые их используют. Если int, связанный с константой перечисления, изменен, его клиенты должны быть перекомпилированы. Если это не так, они все равно будут работать, но их поведение будет неопределенным.

Не существует простого способа перевести константы перечисления int в печатные строки. Если вы напечатаете такую ​​константу или отобразите ее из отладчика, все, что вы увидите, — это число, что не очень полезно. Не существует надежного способа перебрать все константы перечисления int в группе или даже получить размер группы перечисления int.

(+ еще 10 страниц о том, почему перечисления лучше :-))

Источник: Элемент 30. Использование перечисления вместо int констант

person Sean Patrick Floyd    schedule 24.02.2011
comment
Спасибо за это, это очень описательно. - person ahodder; 24.02.2011

Перечисления более четко выражают то, что вы пытаетесь сделать. Используйте их и не беспокойтесь о производительности; влияние на производительность будет незначительным.

person Carl Manaster    schedule 24.02.2011

Эквивалентом использования флагов битовой маски является использование 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
person Peter Lawrey    schedule 24.02.2011

По сути, это одно и то же, за исключением того, что перечисления самодокументированы. Я рекомендую использовать перечисления, как только кто-то еще может связаться с вашим кодом.

person anthonyvd    schedule 24.02.2011
comment
Перечисления в Java — это совсем не то же самое, что целые числа. Они намного мощнее (и чем перечисления в большинстве других языков). - person Michael Borgwardt; 24.02.2011
comment
Вы правы, они более мощные и типобезопасные. Что я, вероятно, не выразил адекватно, так это то, что простая замена флагов int перечислениями даст те же результаты, но в более читаемом виде. - person anthonyvd; 24.02.2011

Тип Enum с собственными методами и оптимизированные контейнеры. Вы должны предпочесть его флагам int, потому что он безопаснее и, возможно, более эффективен (хотя я сомневаюсь, что в нем вообще много чего есть!).

person Jeff Foster    schedule 24.02.2011

В дополнение к безопасному коду у вас есть единственная ссылка для совместного использования коллекции (повторное использование).

person Bruce Chidester    schedule 24.02.2011