Операторы switch с String
делами были реализованы в Java SE 7 , по крайней мере, через 16 лет после их первого запроса. Четкой причины задержки предоставлено не было, но, скорее всего, это было связано с производительностью.
Реализация в JDK 7
В настоящее время эта функция реализована в процессе javac
«удаления сахара»; чистый высокоуровневый синтаксис с использованием String
констант в case
объявлениях расширяется во время компиляции в более сложный код, следуя шаблону. Полученный код использует инструкции JVM, которые существовали всегда.
А switch
с String
делами во время компиляции переводится в два ключа. Первая отображает каждую строку в уникальное целое число - ее положение в исходном переключателе. Это делается путем первого включения хеш-кода метки. Соответствующий случай - это if
оператор, который проверяет равенство строк; если в хэше есть коллизии, тест является каскадным if-else-if
. Второй переключатель отражает это в исходном исходном коде, но заменяет метки регистра соответствующими позициями. Этот двухэтапный процесс позволяет легко сохранить управление потоком исходного переключателя.
Переключатели в JVM
Для большей технической глубины switch
вы можете обратиться к Спецификации JVM, где описана компиляция операторов switch . В двух словах, есть две разные инструкции JVM, которые можно использовать для коммутатора, в зависимости от разреженности констант, используемых в случаях. Оба зависят от использования целочисленных констант для эффективного выполнения каждого случая.
Если константы плотные, они используются в качестве индекса (после вычитания наименьшего значения) в таблицу указателей инструкций - tableswitch
инструкцию.
Если константы редкие, выполняется бинарный поиск правильного регистра - lookupswitch
инструкция.
В де-Обсахаривания switch
на String
объектах, обе инструкции могут быть использованы. lookupswitch
Подходят для первого переключателя на хэш - кодах , чтобы найти исходное положение корпуса. Полученный порядковый номер является естественным соответствием для tableswitch
.
Обе инструкции требуют, чтобы целочисленные константы, назначенные каждому случаю, были отсортированы во время компиляции. Во время выполнения, хотя O(1)
производительность tableswitch
обычно выглядит лучше, чем O(log(n))
производительность lookupswitch
, требуется некоторый анализ, чтобы определить, является ли таблица достаточно плотной, чтобы оправдать компромисс между пространством и временем. Билл Веннерс (Bill Venners) написал отличную статью, которая более подробно описывает это, а также подробное описание других инструкций по управлению потоком Java.
До 7 JDK
До JDK 7 enum
можно было бы приблизиться к String
переключателю на основе. При этом используется статическийvalueOf
метод, сгенерированный компилятором для каждого enum
типа. Например:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}