У вас уже есть хорошие ответы по улучшению использования Enums. Что касается того, почему они лучше строковых констант:
Я думаю, что наибольшим преимуществом является проверка ошибок во время компиляции . Если бы я позвонил growAFruit("watermelon")
, компилятор не знал бы, что что-то не так. И так как я написал это правильно, это не будет выделяться как ошибка при просмотре кода. Но если бы я набрал WATERMELEN.growAFruit()
, компилятор мог бы сразу сказать вам, что я его неправильно написал.
Вы также можете определить growAFruit
как набор простых, удобных для чтения методов вместо большого блока if
- then
- else
с. Это становится еще более очевидным, когда у вас есть несколько десятков фруктов или когда вы начинаете добавлять harvestAFruit()
, packageAFruit()
, sellAFruit()
и т. Д. Без перечислений вы будете копировать свой большой блок if-else повсюду, а если Вы забыли добавить кейс, он будет падать на кейс по умолчанию или ничего не делать, в то время как с помощью перечислений компилятор может сказать вам, что метод не был реализован.
Еще больше преимуществ проверки компилятором: если у вас также есть метод growVegetable
и связанные строковые константы, ничто не помешает вам вызвать growVegetable("pineapple")
или growFruit("peas")
. Если у вас есть "tomato"
константа, единственный способ узнать, считаете ли вы это фруктом или овощем, это прочитать исходный код соответствующих методов. Еще раз, с перечислениями компилятор может сразу сказать вам, если вы сделали что-то не так.
Другое преимущество состоит в том, что он группирует связанные константы вместе и дает им надлежащий дом . В качестве альтернативы можно использовать набор полей public static final
, которые выбрасываются в некоторый класс, который использует их, или прикрепляет интерфейс констант. Интерфейс, полный констант, даже не имеет смысла, потому что если это все, что вам нужно, определить перечисление будет намного проще , чем писать интерфейс. Кроме того, в классах или интерфейсах есть возможность случайно использовать одно и то же значение для более чем одной константы.
Они также повторяемые . Чтобы получить все значения перечисления, вы можете просто позвонить Fruit.values()
, тогда как с константами вам нужно будет создать и заполнить свой собственный массив. Или, если использовать только литералы, как в вашем примере, нет списка разрешенных допустимых значений.
Бонусный раунд: Поддержка IDE
- С помощью enum вы можете использовать функцию автозаполнения IDE и автоматический рефакторинг
- Вы можете использовать такие вещи, как «Найти ссылки» в Eclipse со значениями перечисления, в то время как вам нужно будет выполнить простой текстовый поиск, чтобы найти строковые литералы, которые обычно также возвращают много ложных срабатываний (событие, если вы используете статические конечные константы, кто-то мог где-то использовать строковый литерал)
Основная причина , а не , использовать перечисление, если вы не знаете все возможные значения во время компиляции (т. Е. Вам нужно добавить больше значений во время работы программы). В этом случае вы можете определить их как иерархию классов. Кроме того, не бросайте связку не связанных констант в перечисление и называйте это днем. Должен быть какой-то общий поток, соединяющий значения. Вы всегда можете сделать несколько перечислений, если это более уместно.