Оператор switch — это Java - оператор множественного ветвления. Он пере¬ключает выполнение на различные части кода программы, основываясь на значении выражения, и часто обеспечивает лучшую альтернативу, чем длинный ряд операторов if-eise-if. Общая форма оператора switch:
switch (expression) { case value1: // последовательность операторов1 break; case value2: // последовательность операторов2 break; . . . case valueN: // последовательность операторовN break; default: // последовательность операторов no умолчанию }
Здесь expression должно иметь тип byte, short, int или char; каждое value, указанное в операторах case, должно иметь тип, совместимый с типом выражения. Каждое значение case должно быть уникальной константой (а не переменной). Дублирование значений case недопустимо. Оператор switch работает следующим образом. Значение выражения срав¬нивается с каждым из указанных значений в case-операторах. Если соответ¬ствие найдено, то выполняется кодовая последовательность, следующая по¬сле этого оператора case. Если ни одна из case-констант не соответствует значению выражения, то выполняется оператор default. Однако оператор default необязателен. Если согласующихся case нет, и default не присутст¬вует, то никаких дальнейших действий не выполняется. Оператор break используется внутри switch, чтобы закончить последова¬тельность операторов. Когда встречается оператор break, выполнение пере¬дается к первой строке кода, которая следует за полным оператором switch. Он создает эффект досрочного выхода из switch. Простой пример, который использует оператор switch: // Простой пример с оператором switch, public class SampleSwitch {
public static void main(String[] args) { for (int i = 0; i < 6; i++) { switch (i) { case 0: System.out.println("i равно нулю."); break; case 1: System.out.println("i равно единице."); break; case 2: System.out.println("i равно двум."); break; case 3: System.out.println("i равно трем."); break; default: System.out.println("i больше трех."); } } } } Вывод этой программы:
i равно нулю. i равно единице. i равно двум. i равно трем. i больше трех. i больше трех.
Не трудно заметить, что на каждом проходе цикла выполняются операторы, связанные с case-меткой, которая соответствует переменной цикла i. Все другие case-ветви обходятся. После того как i становится больше трех, ни¬какого соответствия case-меткам не возникает, поэтому выполняется опера¬тор default. Оператор break — необязательный. Если он пропускается, выполнение бу¬дет продолжено со следующей case-метки. Иногда желательно иметь мно¬жественные case-ветви без операторов break между ними. Например, рас¬смотрим следующую программу:
// switch с пропущенными операторами break,
public class MissingBreak {
public static void main(String args[]) {
{ for (int i = 0; i < 12; i++) { switch (i) { case 0: case 1: case 2: case 3: case 4: System.out.println("i меньше 5"); break; case 5: case 6: case 7: case 8: case 9: System.out.println("i меньше 10"); break; default: System.out.println("i равно 10 или больше"); } } } } } Эта программа генерирует следующий вывод: i меньше 5 i меньше 5 i меньше 5 i меньше 5 i меньше 5 i меньше 10 i меньше 10 i меньше 10 i меньше 10 i меньше 10 i равно 10 или больше i равно 10 или больше
Можно видеть, что выполнение проходит через каждый case, пока не встре¬чается оператор break (или не будет достигнут конец оператора switch). Хотя предшествующий пример придуман, конечно, ради иллюстрации, про¬пуск оператора break имеет много практических приложений в реальных программах. Чтобы показать более жизненное использование switch, рас¬смотрим следующий вариант примера с временами года, приведенного ра¬нее. Эта версия использует switch, чтобы обеспечить более эффективную реализацию. // Улучшенная версия программы с временами года. public class Switch {
public static void main(String[] args) { int month = 4; String season; switch (month) { case 12: case 1: case 2: season = "Зима"; break; case 3: case 4: case 5: season = "Весна"; break; case 6: case 7: case 8: season = "Лето"; break; case 9: case 10: case 11: season = "Осень"; break; default: season = "Непонятный месяц"; } System.out.println("Апрель это " + season + "."); } }
Вложенные switch-операторы Вы можете использовать switch как часть последовательности операторов некоторого внешнего switch. Это называется вложенным switch. Так как switch-оператор определяет свой собственный блок, никакие конфликты между case-метками во внутреннем и внешнем switch не возникают. На¬пример, следующий фрагмент совершенно законен:
switch(count) { case 1: switch(target) { // вложенный switch case 0: System.out.println("target равен нулю"); break; case 1: // нет конфликтов с внешним switch System.out.print In("target равен единице"); break; } break; case 2: // . . . }
Здесь утверждение с меткой case 1 во внутреннем switch не находится в противоречии с утверждением case 1 во внешнем switch. Переменная count сравнивается только с case-меткой на внешнем уровне. Если count равна 1, то переменная target сравнивается с внутренней case-меткой. Обратите внимание на три важные особенности оператора switch.
• Switch отличается от if тем, что может проверять только равенство (своей переменной с case-метками), тогда как if может оценивать любой тип булевского выражения. То есть, switch отыскивает только соответст¬вие между значением выражения и одной из его case-меток. • Никакие две case-метки внутри switch не могут иметь идентичных зна¬чений. Однако операторы switch, включенные во внешний switch, могут, конечно, иметь общие case-метки с внутренним switch. • Оператор switch обычно более эффективен, чем набор вложенных if.
Последний пункт особенно интересен, потому что он дает возможность по¬нять, как работает компилятор Java. Когда компилируется оператор switch, компилятор Java просматривает каждую из case-констант и создает "таблицу переходов", которая будет использоваться для выбора пути выполнения в зависимости от значения выражения. Поэтому, если нужно выбирать среди большой группы значений, оператор switch, выполнится намного быстрее, чем эквивалентная кодированная логика, использующая последовательности if-else. Компилятор может делать это, т. к. он знает, что все case- константы имеют один и тот же тип и просто должны быть проверены на равенство с выражением оператора switch. Компилятор не имеет аналогич¬ных знаний длинного списка выражений if.
|