Когда я начинал программировать на Java, тот факт, что операторы switch не принимают строки, расстраивал меня. Затем, используя Enums, я понял преимущества, которые вы получаете с ними, вместо того, чтобы передавать необработанные значения - безопасность типов (что упрощает рефакторинг), а также ясность для других разработчиков.
Я изо всех сил пытаюсь придумать ситуацию, когда с SE7 я теперь решу использовать переключатель со строками в качестве входов, а не Enums. Если они реализованы с помощью переключения целых строк (например, вместо частичных или регулярных выражений), кажется, что у кода меньше причин для изменения кода.
А с инструментами IDE и соотношением кодирования для чтения и записи, я был бы намного счастливее автоматически генерировать дополнительный Enum, чем передавать строковые значения.
Какую пользу они приносят нам как программистам? Меньше котельной плиты?
Не похоже, что язык кричал об этой функции. Хотя, может быть, есть сценарий использования, который я пропускаю.
источник
Ответы:
Насколько я могу судить, вопрос в том, почему включение констант String в enum не считается достаточным для удовлетворения потребностей языковых пользователей. Об этом говорится в официальном предложении, объявленном в списке рассылки JDK 7 (Project Coin).
Согласно моему прочтению, альтернатива использованию перечислений была отклонена на том основании, что она вводит вздутия типов. Для вашего удобства ниже приводится соответствующая часть предложения, причем заявление, касающееся перечислений, выделено жирным шрифтом :
источник
Помимо того, что код становится более читабельным, существует потенциальный выигрыш в производительности по
if/else if
сравнению со сравнениями. Стоит ли изменение, зависит от того, сколько сравнений вы бы сделали. Строковый переключатель будет выпущен как две отдельные инструкции переключения. Действует на первый хэш - кодов, так что он имеет тенденцию бытьlookupswitch
, в конечном счете , получаяO(log n)
сложность. Второе всегда идеальноO(1)
tableswitch
, так что сложная сложность остаетсяO(log n)
. Одиночная линейная цепочкаif/else if
утверждений дала бы немного худшуюO(n)
сложность.Если вы сравниваете больше, чем, скажем, три строки, то,
switch
вероятно, более читаем и компактен. Вероятно, он будет работать лучше, хотя вы вряд ли заметите разницу, если не будете выполнять большое количество сравнений в горячем коде.источник
if/else
блок плохой практикой, но на данный момент у меня не было бы особой причины его использовать.Переключатель для строк может быть использован, когда ваши
enum
значения поступают извне, то есть хранятся в базе данных.Еще одна примечательная вещь в JDK 7
switch
- это то, что он гораздо более перфоман, чемif-else
конструкции.И хорошим вариантом использования быстрых строковых
switch
файлов может быть анализ потока JSON / XML, когда вам нужно сделать много переключений на типах узлов и атрибутов. Я не могу придумать лучшего варианта для этого.источник
enum
в этом случае можно использовать s из-за статической природы Java. Когда я писал это, я думал оRole
библиотеке безопасности, которая обычно предоставляется в виде класса и не может быть помещена в нееenum
. Другой случай - это динамически скомпилированный код Java / Groovy - в этой ситуации, которая, однако, встречается редко, переключатели строк могут быть лучшим вариантом.Простота
Поддержка String в Switch полезна для обработки данных без преобразования в перечисление или
if-else
логику. Иногда просто включить String.Из предложения функций в списке рассылки JDK 7 (Project Coin) ( @gnat answer )
Версия If-Else
Это коротко, но многие
if's
трудно читать. И это медленно.Enum версия
Перечисления должны быть определены, это хорошо, но иногда не нужно.
Обрабатывать как обычно
JDK 7 - Строки в версии операторов Switch
Мы можем обрабатывать без конвертации и определения дополнительных типов.
источник
Большинство улучшений на любом языке - сделать код проще для чтения. Я предпочитаю читаемый код над фантазией в любой день.
Вы можете не верить этому, но попробуйте:
источник
Перечисления великолепны, и вы должны использовать их вместо строк, если у вас есть такая возможность. Но бывают случаи, когда вы просто не можете, например, когда вам нужно работать с каким-то внешним объектом, приходящим извне Java. Представь, что тебе надо что-то разобрать. Например, ответ сервера, конфигурация, файл журнала или что-то подобное: у вас есть куча опций, которые вы ищете, и нет никаких способов перечислить их. Так что в Java <7 вы застряли бы с кучей
Вы все еще можете использовать перечисления в этом случае, просто пытаясь получить их по именам и / или предоставив пользовательскую подпрограмму String-> Enum, но иногда это невозможно или просто нецелесообразно (например, когда вам нужно создать слишком много перечислений)
TLDR : вам обязательно следует использовать Enums, когда вы работаете исключительно с Java-кодом, но это не всегда возможно с внешними объектами. Я надеюсь, что мое объяснение имеет смысл.
источник
if
утверждениях, то вам все равно следует обернуть их , что означает, что вы все равно можете использовать перечисления или шаблон команд и т. Д.Я не согласен с мнением, что это более чистый и читаемый код, когда вы используете
Strings
в операторах switch, и считаю, что это плохая практика программирования. Если вы изменяете значение, которое используете для хранения, вы должны менять его при каждом переключении или возникновении if-elseif. Это нехорошо, поскольку вы ставите жестко закодированные значения для каждого элемента кода. Что вы будете делать, если однажды решите изменить одно из этих жестко закодированных значений? Поиск и замена каждой его копии?Если у вас есть некоторые жестко закодированные значения, которые вы делаете в операторах if-elseif, использование постоянных примитивных значений для них намного лучше, чем в Java 1.5, только потому, что это обеспечивает безопасность типов.
ОК, будут ситуации, когда вы получите строковые значения (из HTTP-запроса, файлов и т. Д.), И преобразование их в примитивные значения - большая проблема. Но
Enum
с этой точки зрения все хорошо. Потому что, когда вы хотите изменить значение, которое вы храните в Enum, просто измените его при объявлении. Нет необходимости изменять что-либо еще в вашем коде. (Вам, конечно, нужно изменить значения, хранящиеся где-то еще).Конечно, если вы просто реализуете грязный и ленивый код, это прекрасно. Вы не хотите привлекать к написанию большого количества программ
Enum
, но в большом сложном программном обеспечении, которое вас убьет.источник
Если вы знаете, какая информация поступает и что она может иметь только 5 состояний, тогда используйте
Enum
. Однако, если возможные состояния могут быть больше 9000, и вам нужно только найти 42, тогда лучше использовать переключатель, потому что вы не хотите выводить все эти состояния.Enum имеет тенденцию быть выбором большинством в большинстве случаев, за исключением случаев, когда возможные состояния неизвестны или их много, и вас волнуют только некоторые из них.
Но почему они ввели это сейчас? Это было просто изменение, которое позволило более чистый код.
В версии 1.5 они также позволяли вам создавать собственные тела для Enums.
источник
default
вswitch
приходит к игре. Я не знаю, что вы можете иметь состояние по умолчанию сEnum
, если вы не установите состояние по умолчанию, но тогда этот код просто раздут, тогда как использование aswitch
намного чище.UNKNOWN
состояние в Enum является раздутым, аdefault
случай с переключателем - нет.