Почему я не могу использовать оператор switch для String?

То, что я использую

find . \( -name "*.h" -o -name "*.cpp" \) -print
970
задан Mahozad 9 July 2018 в 21:52
поделиться

5 ответов

Операторы переключения с String случаи были реализованы в [1 124] Java SE 7, по крайней мере 16 лет после того, как их сначала требовали. А ясная причина задержки не была обеспечена, но это, вероятно, имело отношение к производительности.

Реализация в JDK 7

опция была теперь реализована в javac с процессом "de-sugaring"; чистый, высокоуровневый синтаксис с помощью String константы в case объявления расширен во время компиляции в более сложный код после шаблона. Получающийся код использует инструкции по JVM, которые всегда существовали.

А switch с String случаи переводится в два переключателя во время компиляции. Первые карты каждая строка к уникальному integer— его положение в исходном переключателе. Это сделано первым включением хэш-кода маркировки. Соответствующий случай if оператор, который тестирует строковое равенство; если существуют коллизии на хеше, тест является расположением каскадом if-else-if. Вторые зеркала переключателя, что в коде первоисточника, но заменах случай маркирует их соответствующими положениями. Этот двухступенчатый процесс облегчает сохранять управление потоком исходного переключателя.

Переключатели в JVM

Для большей технической глубины на switch, можно обратиться к Спецификации JVM, где компиляция операторов переключения описана. Короче говоря существует две различных инструкции по JVM, которые могут использоваться для переключателя, в зависимости от разреженности констант, используемых случаями. Оба зависят от использования целочисленных констант для каждого случая для выполнения эффективно.

, Если константы являются плотными, они используются в качестве индекса (после того, как, вычитая самое низкое значение) в таблицу инструкции pointers— tableswitch инструкция.

, Если константы редки, двоичный поиск корректного случая является performed— lookupswitch инструкция.

В de-sugaring switch на [1 113] объекты, обе инструкции, вероятно, будут использоваться. Эти lookupswitch подходит для первого, включают хэш-коды для нахождения исходного положения случая. Получающийся ординал является естественным пригодным для tableswitch.

Обе инструкции требуют, чтобы целочисленные константы, присвоенные каждому случаю, были отсортированы во время компиляции. Во времени выполнения, в то время как O(1) производительность [1 117] обычно кажется лучше, чем O(log(n)) производительность [1 119], это требует, чтобы некоторый анализ определил, является ли таблица достаточно плотной для выравнивания по ширине space– компромисс времени. Bill Venners записал большая статья , которая касается этого более подробно, наряду со взглядом под капотом на другие инструкции по управлению потоком Java.

, Прежде чем JDK 7

До JDK 7, enum мог приблизиться String - базирующийся переключатель. Это использует помехи valueOf метод, сгенерированный компилятором на каждом enum тип. Например:

Pill p = Pill.valueOf(str);
switch(p) {
  case RED:  pop();  break;
  case BLUE: push(); break;
}
981
ответ дан erickson 9 July 2018 в 21:52
поделиться

James Curran кратко говорит: "Переключатели на основе целых чисел могут быть оптимизированы к очень efficent код. Переключатели на основе другого типа данных могут только быть скомпилированы в серию если () операторы. По этой причине C & C++ только позволяет, включает целые типы, так как это было бессмысленно с другими типами".

Мое мнение, и это только, что, то, что, как только Вы начинаете включать непримитивы, необходимо начать думать о, "равняется" по сравнению с "==". Во-первых сравнение двух строк может быть довольно длинной процедурой, добавив к проблемам производительности, которые упомянуты выше. Во-вторых, если там включит строки то будет спрос на включение строк, игнорирующих регистр, включая строки, рассматривая/игнорируя локаль, включая строки на основе regex.... Я одобрил бы решение, которое сэкономило много времени для разработчиков языка за счет небольшого количества времени для программистов.

18
ответ дан DJClayworth 9 July 2018 в 21:52
поделиться

Если у Вас есть место в Вашем коде, где можно включить Строку, то может быть лучше осуществить рефакторинг Строку, чтобы быть перечислением возможных значений, которые можно включить. Конечно, Вы ограничиваете потенциальные ценности Строк, которые Вы можете иметь тем в перечислении, которое может или не может быть желаемо.

, Конечно, Ваше перечисление могло иметь запись для 'другого' и fromString (Строка) метод, тогда Вы могли иметь

ValueEnum enumval = ValueEnum.fromString(myString);
switch (enumval) {
   case MILK: lap(); break;
   case WATER: sip(); break;
   case BEER: quaff(); break;
   case OTHER: 
   default: dance(); break;
}
120
ответ дан JeeBee 9 July 2018 в 21:52
поделиться

Переключатели на основе целых чисел могут быть оптимизированы к очень efficent код. Переключатели на основе другого типа данных могут только быть скомпилированы в серию если () операторы.

По этой причине C & C++ только позволяет, включает целые типы, так как это было бессмысленно с другими типами.

разработчики C# решили, что стиль был важен, даже если не было никакого преимущества.

разработчики Java, по-видимому, думали как разработчики C.

25
ответ дан James Curran 9 July 2018 в 21:52
поделиться

Около вышеупомянутых хороших аргументов я добавлю, что партия людей сегодня видит switch как устаревший остаток от процедурного прошлого Java (назад ко временам C).

я не полностью совместно использую это мнение, я думаю switch, может иметь его полноценность в некоторых случаях, по крайней мере, из-за его скорости, и так или иначе это лучше, чем некоторый ряд расположения каскадом числового else if, я видел в некотором коде...

, Но действительно, стоит посмотреть на случай, где Вы нуждаетесь в переключателе и видите, не может ли это быть заменено чем-то больше OO. Например, перечисления в Java 1.5 +, возможно, HashTable или некоторый другой набор (когда-то я сожалею, что у нас нет (анонимных) функций как у гражданина первого класса, как в Lua —, который не имеет переключателя — или JavaScript), или даже полиморфизм.

12
ответ дан PhiLho 9 July 2018 в 21:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: