28 апр. 2015 г.

Оператор switch

Оператор switch состоит из выражения и тела, которое содержит различные пронумерованные точки входа. Выражение вычисляется, и управление переходит на точку входа, определенную полученным значением. Выражение должно возвращать следующие тип данных: int, short, char, byte (или их обертки), String (с Java 7) или enum. Тип данных enum мы пока не проходили.

Общая форма оператора switch имеет следующий вид:

sw01

Часто он оказывается эффективнее применения длинных последовательностей операторов if-else-if.

Например, программу из предыдущего поста можно переписать таким образом:

sw02

И варианты исполнения программы:

sw03

При выполнении оператора switch интерпретатор вычисляет значение выражения в круглых скобках, а затем ищет метку case, соответствующую полученному значению. Если интерпретатор находит метку, он начинает выполнять блок программы с первого оператора после метки case. Если интерпретатор не находит метку case с соответствующим значением, он начинает выполнение блока с первого оператора после специальной метки default:. Или, если нет метки default:, интерпретатор выполняет только соответствующий метод case если он есть, либо не выполняет ни какой если нет подходящей метки.

Можете попробовать закомментировать в предыдущем примере выполнение метки default и посмотреть как будет выполнятся программа.

sw04

Обратите внимание на использование ключевого слова break в конце каждого case в предыдущем коде. Оператор break будет описан чуть позже; в данном случае он заставляет интерпретатор покинуть оператор switch. Метки case определяют только на чальную точку нужного кода. Отдельные варианты не являются независимыми блоками программы и не содержат никакой неявной точки окончания. Поэтому при помощи оператора break или другого подходящего оператора нужно явно определить окончание каждого варианта. Если нет оператора break, оператор switch начинает выполнять код с первого оператора после соответствующей метки case и продолжает выполнять операторы, пока не достигнет конца блока. Иногда удобно писать код с последовательным переходом от одной метки case к другой, однако в 99% случаев вам придется завершать каждый раздел case и default оператором, приводящим к завершению выполнения оператора switch. Обычно в таких случаях применяют оператор break, но также подходят return и throw. Как только программа доходит до оператора break (rerturn, throw), она продолжает выполнение с первой строки кода, следующей за всем оператором switch.

Оператор switch может содержать более одной метки case для одного и того же оператора. По существу это спользование нескольких операторов case без разделяющих их операторов break.

sw05

Есть несколько важных ограничений для оператора switch и его меток caseВо-первых типы с плавающей точкой и boolean не поддерживаются. То же самое относится к long, хотя long является целым типом. Во-вторых, значение, ассоциируемое с каждой меткой case, должно быть постоянным значением или выражением, которое может вычислить компилятор. Например, метка case не может содержать выражение, вычисляемое во время выполнения – с переменными и вызовами методов. В-третьих, значения меток case должны соответствовать типу данных выражения switch. И наконец, не разрешается создавать две и более метки case с одинаковым значением или больше одной метки default.

Вложенные операторы switch

Оператор switch можно использовать в последовательности операторов внешнего оператора switch. Такой оператор называютвложенным оператором switch. Поскольку оператор switch определяет собственный блок, каких-либо конфликтов между константами case внутреннего и внешнего операторов switch не происходит. Например, следующий фрагмент полностью допустим:

sw06

В данном случае оператор case1:  внутреннего оператора switch не конфликтует с оператором case1:  внешнего оператора switch. Программа сравнивает значение переменной count только со списком ветвей case внешнего уровня. Если значение count равно 1, программа сравнивает значение переменной target c внутренним списком ветвей case.

Ну и на последок можно сказать, что как правило, оператор switch эффективнее набора вложенных операторов if. Это свойство представляет особый интерес, поскольку позволяет понять работу компилятора Java. Компилируя оператор switch, компилятор Java будет проверять каждую из констант case и создавать “таблицу переходов”, которую будет использовать для выбора ветви программы в зависимости от значения выражения. Поэтому в тех случаях, когда требуется осуществлять выбор в большой группе значений, оператор switch будет выполняться значительно быстрее последовательности операторов if-else. Это обусловлено тем, что компилятору известно, что все константы case имеют один и тот же тип, и их нужно просто проверять на предмет равенства значению выражения switch. Компилятор не располагает подобными сведениями о длинном списке выражений оператора if.

Комментариев нет:

Отправить комментарий