Switch and case android

Содержание
  1. Оператор switch
  2. Подробно про оператор switch в Java
  3. Синтаксис оператора switch
  4. Пример 1
  5. Пример 2: создание калькулятора с использованием оператора switch
  6. Пример 3
  7. Заявление break
  8. Переключение Аргумента и регистра значений
  9. Типы данных
  10. Нет null значений
  11. Значения регистра как константы времени компиляции
  12. Сравнение строк
  13. switch выражения
  14. Новое выражение переключателя
  15. Ключевое слово yield
  16. Возврат внутри выражения переключателя
  17. Полное руководство по switch-выражениям в Java 12
  18. Предварительный обзор
  19. Проблема с операторами в switch
  20. Представляем switch-выражения!
  21. Выражение или оператор
  22. Стрелка или двоеточие
  23. Подробнее об эволюции switch
  24. Несколько меток на case
  25. Типы за пределами Enum
  26. Подробнее о стрелке
  27. Отсутствие сквозного перехода к следующему case
  28. Блоки операторов
  29. Подробнее о выражениях switch
  30. Множественные выражения
  31. Ранний возврат
  32. Покрытие всех вариантов
  33. Размышление

Оператор switch

В отличие от операторов if-then и if-then-else, оператор switch применим к известному числу возможных ситуаций. Можно использовать простые типы byte, short, char, int. Также можно использовать Enum и String (начиная с JDK7), и специальные классы, которые являются обёрткой для примитивных типов: Character, Byte, Short, Integer.

Дублирование значений case не допускается. Тип каждого значения должен быть совместим с типом выражения.

Команду switch часто называют командой выбора. Выбор осуществляется в зависимости от целочисленного выражения. Форма команды выглядит так:

Параметр ВыражениеДляСравнения — выражение, в результате вычисления которого получается целое число (как правило). Команда switch сравнивает результат ВыражениеДляСравнения с каждым последующим Совпадением. Если обнаруживается совпадение, то исполняется команда или набор команд, которые прописаны за данным оператором. Если совпадений не будет, то исполняется команда после ключевого слова default. Однако оператор default не является обязательным. В этом случае при отсутствии совпадений программа не выполняет никаких действий.

Каждая секция case обычно заканчивается командой break, которая передаёт управление к концу команды switch.

Рассмотрим простейший пример с месяцами. Запустим наш учебный проект и добавим код в обработчик нажатия кнопки:

Запустите проект и нажмите кнопку — в текстовом поле появится слово Март (любимый месяц котов).

При желании, можно переписать пример с использованием if-then-else:

В каждом блоке case имеется оператор break, который прерывает свой блок кода. Его нужно использовать обязательно, иначе выполнение кода продолжится. Хотя иногда это и используется.

Если код в блоках case совпадает, то блоки можно объединить. Например, код для подсчёта дней в месяце:

При изучении оператора if мы рассматривали пример с временами года. Перепишем его с использованием оператора switch:

Следующий пример случайным образом генерирует английские буквы. Программа определяет, гласные они или согласные:

Так как метод Random.nextInt(26) генерирует значение между 0 и 26, для получения символа нижнего регистра остаётся прибавить смещение ‘a’, при этом символ a автоматически преобразуется к типу int. Символы в секциях case также представляют собой целочисленные значения, используемые для сравнения.

Чтобы вывести переменную c в символьном виде, её необходимо преобразовать к типу char, иначе значение будет выведено в числовом виде.

В Java SE 7 появилась возможность использовать объект String в операторе switch. Возможно, это будет работать и на Android в будущем (Upd.: вроде уже работает):

Допустимы вложенные операторы switch, но на практике я не сталкивался с таким кодом.

Запомните важные свойства оператора switch:

  • Оператор switch отличается от оператора if тем, что может выполнять проверку только равенства, а оператор if может вычислять результат булева выражения любого типа.
  • Две константы case в одном и том же операторе switch не могут иметь одинаковые значения
  • Оператор switch эффективнее набора вложенных операторов if

Источник

Подробно про оператор switch в Java

В этом руководстве вы научитесь использовать оператор switch в Java для управления потоком выполнения вашей программы.

В Java мы использовали if..else..if для выполнения блока кода среди нескольких блоков. Однако синтаксис if … else … if слишком длинный.

Следовательно, мы можем использовать оператор switch вместо длинных if … else … if. Использование операторов switch делает наш код более читабельным.

Switch эволюционировал со временем – были добавлены новые поддерживаемые типы, особенно в Java 5 и 7. Кроме того, он продолжает развиваться – выражения switch, вероятно, будут введены в Java 12.

Синтаксис оператора switch

Оператор switch оценивает выражение (в основном переменное) и сравнивает его со значениями (могут быть выражениями) каждой метки case.

Теперь, если значение соответствует определенной метке case, то выполняются все операторы соответствующей метки case.

Например, если переменная / выражение равно значению 2. В этом случае выполняются все операторы этого совпадающего case (операторы case2).

Обратите внимание, что в каждом случае используются операторы break. Оператор break используется для завершения выполнения оператора switch.

Это важно, потому что если break не используется, все операторы после соответствующего case выполняются последовательно до конца оператора switch.

Что следует помнить:

  • Для выражения переключения может быть одно или N значений case.
  • Значение case должно быть только типа выражения переключения. Значение case должно быть буквальным или постоянным. Он не допускает переменных.
  • Значения case должны быть уникальными. В случае повторяющегося значения он отображает ошибку времени компиляции.
  • Выражение переключателя Java должно быть byte, short, int, long, перечислением и строкой.
  • Каждый оператор case может иметь оператор break, который не является обязательным.
  • Когда элемент управления достигает оператора break, он переходит к элементу управления после выражения switch.
  • Также case может иметь метку по умолчанию, которая является необязательной.

Пример 1

The day is Wednesday

В приведенном выше примере мы использовали оператор switch, чтобы узнать день недели. Здесь у нас есть переменная неделя, которая содержит целочисленное значение. Значение сравнивается с каждым случаем внутри блока переключателя.

Здесь значение недели равно 4. Следовательно, оно соответствует случаю 4. Таким образом, выполняется оператор внутри случая 4.

Пример 2: создание калькулятора с использованием оператора switch

Программа ниже принимает от пользователя три ввода: один оператор и 2 числа. На основе оператора, предоставленного пользователем, он выполняет расчет чисел. Затем результат отображается на экране.

Читайте также:  Unfortunately the process com android systemui has stopped что делать

Перед тем как приступить к работе с программой, убедитесь, что вы знаете о Java Scanner, чтобы принимать данные от пользователя.

Вывод:
Enter operator (either +, -, * or /): *
Enter number1 and number2 respectively: 1.4
-5.3
1.4*-5.3 = -7.419999999999999

В приведенном выше примере мы использовали оператор switch для создания калькулятора на Java. Он выполняет расчет на основе оператора, предоставленного пользователем.

Пример 3

Допустим, у нас есть следующие вложенные операторы if-else:

Приведенный выше код выглядит не очень хорошо, и его будет сложно поддерживать и обдумывать. Чтобы улучшить читаемость, мы могли бы использовать здесь оператор switch:

Как показано выше, мы сравниваем animal аргумента switch с несколькими значениями case. Если ни одно из значений case не равно аргументу, то выполняется блок под меткой по умолчанию.

Проще говоря, оператор break используется для выхода из оператора switch.

Заявление break

Хотя большинство операторов switch в реальной жизни подразумевают, что должен быть выполнен только один из блоков case, оператор break необходим для выхода из switch после завершения блока.

Чтобы продемонстрировать это, опустим операторы break и добавим вывод в консоль для каждого блока:

Давайте выполним этот код ForgotBreakInSwitch(«DOG») и проверим вывод, чтобы убедиться, что все блоки выполняются:

domestic animal
unknown animal

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

Единственный блок, в котором не требуется разрыв, – это последний, но добавление разрыва к последнему блоку делает код менее подверженным ошибкам.

Мы также можем воспользоваться этим поведением, чтобы опустить break, когда мы хотим, чтобы один и тот же код выполнялся для нескольких операторов case. Давайте перепишем пример из предыдущего раздела, сгруппировав первые 2 случая:

Переключение Аргумента и регистра значений

Теперь давайте обсудим допустимые типы аргументов switch и значений case, требования к ним и то, как оператор switch работает со строками.

Типы данных

Мы не можем сравнивать все типы объектов и примитивов в операторе switch. Переключатель работает только с четырьмя примитивами и их оболочками, а также с типом перечисления и классом String:

  • byte and Byte;
  • short and Short;
  • int and Integer;
  • char and Character;
  • enum;
  • String.

Тип String доступен в операторе switch, начиная с Java 7. Тип перечисления был представлен в Java 5 и с тех пор доступен в операторе switch. Классы-оболочки также доступны с Java 5.

Конечно, аргументы переключателя и значения case должны быть одного типа.

Нет null значений

Мы не можем передать нулевое значение в качестве аргумента инструкции switch. Если мы это сделаем, программа выдаст исключение NullPointerException, используя наш первый пример переключения:

Конечно, мы также не можем передать null как значение в метку case оператора switch. Если мы это сделаем, код не скомпилируется.

Значения регистра как константы времени компиляции

Если мы попытаемся заменить значение case DOG переменной dog, код не будет компилироваться, пока мы не отметим переменную dog как final:

Сравнение строк

Если оператор switch использовал оператор равенства для сравнения строк, мы не смогли бы правильно сравнить аргумент String, созданный с помощью оператора new, со значением case String.

К счастью, оператор switch использует скрытый метод equals().

switch выражения

JDK 13 теперь доступен и содержит улучшенную версию новой функции, впервые представленной в JDK 12: выражения switch.

Чтобы включить его, нам нужно передать компилятору параметр –enable-preview.

Новое выражение переключателя

Давайте посмотрим, как выглядит новое выражение переключения при переключении через несколько месяцев:

Отправка значения типа Month.JUNE установит результат в 3.

Обратите внимание, что новый синтаксис использует оператор -> вместо двоеточия, которое мы использовали с операторами switch. Кроме того, нет ключевого слова break: выражение switch не пропускает регистры. Еще одним дополнением является тот факт, что теперь у нас могут быть критерии, разделенные запятыми.

Ключевое слово yield

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

Возврат внутри выражения переключателя

Вследствие различия между операторами switch и выражениями переключения, можно вернуться изнутри оператора, но нам не разрешено делать это из выражения.

Следующий пример вполне допустим и будет компилироваться:

Однако следующий код не будет компилироваться, поскольку мы пытаемся выполнить возврат за пределами включающего выражения переключателя:

При использовании операторов switch на самом деле не имеет значения, охвачены ли все случаи.

Следующий код, например, имеет место быть:

Однако для выражений переключения компилятор настаивает на том, чтобы были учтены все возможные случаи. Следующий фрагмент кода, например, не будет компилироваться, так как нет случая по умолчанию и не все возможные случаи рассмотрены:

Выражение switch, однако, будет действительным, когда будут рассмотрены все возможные случаи, как в следующем примере:

Обратите внимание, что в приведенном выше фрагменте кода нет регистра по умолчанию. Пока рассмотрены все случаи, выражение switch будет действительным.

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.

Или поделись статьей

Видим, что вы не нашли ответ на свой вопрос.

Источник

Полное руководство по switch-выражениям в Java 12

Старый добрый switch был в Java с первого дня. Мы все используем его и привыкли к нему — особенно к его причудам. (Кого-нибудь еще раздражает break ?) Но теперь все начинает меняться: в Java 12 switch вместо оператора стал выражением:

В switch появилась возможность возвращать результат своей работы, который можно присвоить переменной; вы также можете использовать синтаксис в стиле «лямбда», который позволяет избавиться от сквозного прохода по всем case , в которых нет оператора break .

В этом руководстве я расскажу Вам обо всем, что необходимо знать о switch-выражениях в Java 12.

Читайте также:  Sony playstation для android

Предварительный обзор

Это означает, что данная управляющая конструкция может быть изменена в будущих версиях спецификации языка.

Что бы начать использовать новую версию switch необходимо применить опцию командной строки —enable-preview как во время компиляции, так и во время запуска программ (также необходимо использовать —release 12 при компиляции — примечание переводчика).

Так что имейте ввиду, что switch, как выражение, не имеет на данный момент окончательного варианта синтаксиса в Java 12.

Если у вас возникло желание поиграть со всем этим самим, то вы можете посетить мой демо-проект Java X на гитхабе.

Проблема с операторами в switch

Прежде, чем мы перейдем к обзору нововведений в switch, давайте быстро оценим одну ситуацию. Допустим, мы столкнулись с «ужасным» тернарным булеаном и хотим преобразовать его в обычный булеан. Вот один из способов сделать это:

Согласитесь, что это очень неудобно. Как и многие другие варианты switch, встречающиеся в «природе», представленный выше пример просто вычисляет значение переменной и присваивает его, но реализация обходная (объявляем идентификатор result и используем его позже), повторяющаяся (мои break ‘и всегда результат copy-pasta) и подвержена ошибкам (забыл еще одну ветку? Ой!). Тут явно есть, что улучшить.

Давайте попробуем решить эти проблемы, поместив switch в отдельный метод:

Так намного лучше: отсутствует фиктивная переменная, нет break ‘ов, загромождающих код и сообщений компилятора об отсутствии default (даже если в этом нет необходимости, как в данном случае).

Но, если подумать, то мы не обязаны создавать методы только для того, чтобы обойти неуклюжую особенность языка. И это даже без учёта, что такой рефакторинг не всегда возможен. Нет, нам нужно решение получше!

Представляем switch-выражения!

Как я показал в начале статьи, начиная с Java 12 и выше, вы можете решить вышеуказанную проблему следующим образом:

Я думаю, что это довольно очевидно: если ternartBool равен TRUE , то result ‘у будет присвоено true (иными словами TRUE превращается в true ). FALSE становится false .

Сразу возникают две мысли:

  • switch может иметь результат;
  • что там со стрелками?

Прежде чем углубляться в детали новых возможностей switch, в начале я расскажу об этих двух основных аспектах.

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

Возможно, вы удивлены, что switch теперь является выражением. А чем же он был до этого?

До Java 12 switch был оператором — императивной конструкцией, регулирующей поток управления.

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

Разница в том, что if просто выполняет соответствующий блок, тогда как тернарный оператор возвращает какой-то результат:

То же самое для switch: до Java 12, если вы хотели вычислить значение и сохранить результат, то должны были либо присвоить его переменной (а затем break ), либо вернуть из метода, созданного специально для оператора switch .

Теперь же всё выражение оператора switch оценивается (выбирается для выполнения соответствующая ветка), и результат вычислений может быть присвоен переменной.

Еще одним отличием между выражением и оператором является то, что выражение switch, поскольку оно является частью оператора, должно заканчиваться точкой с запятой, в отличие от классического оператора switch.

Стрелка или двоеточие

В вводном примере использовался новый синтаксис в лямбда-стиле со стрелкой между меткой и выполняющейся частью. Важно понимать, что для этого не обязательно использовать switch в качестве выражения. Фактически, пример ниже эквивалентен приведенному в начале статьи коду:

Обратите внимание, что теперь вы можете использовать break со значением! Это идеально согласуется с инструкциями switch старого стиля, которые используют break без какого-либо значения. Так в каком случае стрелка означает выражение вместо оператора, для чего она здесь? Просто хипстерский синтаксис?

Исторически сложилось, что метки с двоеточием просто отмечают точку входа в блок операторов. С этого места начинается выполнение всего кода ниже, даже когда встречается другая метка. В switch нам это известно, как сквозной переход к следующему case (fall-through): метка case определяет, куда перепрыгивает поток управления. Для его завершения нужен break или return .

В свою очередь, использование стрелки означает, что будет выполнен только блок справа от нее. И никакого «проваливания».

Подробнее об эволюции switch

Несколько меток на case

До сих пор каждый case содержал только одну метку. Но теперь все изменилось — один case может соответствовать нескольким меткам:

Поведение должно быть очевидным: TRUE и FALSE приводят к одному и тому же результату — вычисляется выражение «sane».

Это довольно приятное нововведение, которое пришло на смену множественному использованию case , когда требовалось реализовать сквозной переход к следующему case .

Типы за пределами Enum

Все примеры со switch в этой статье используют enum . А как насчет других типов? Выражения и операторы switch также могут работать с String , int , (проверьте документацию) short , byte , char и их обертками. Здесь пока что ничего не изменилось, хотя идеи об использовании таких типов данных, как float и long по прежнему остаются в силе (со второго по последний абзац).

Подробнее о стрелке

Давайте рассмотрим два свойства, характерных для стрелочной формы записи разделителя:

  • отсутствие сквозного перехода к следующему case ;
  • блоки операторов.

Отсутствие сквозного перехода к следующему case

Вот, что говорится в JEP 325 об этом:

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

Я полностью согласен и приветствую возможность использовать switch без поведения по умолчанию:

Важно усвоить, что это не имеет никакого отношения к тому, используете ли вы switch в качестве выражения или оператора. Решающим фактором тут является стрелка против двоеточия.

Читайте также:  Что делать при утере смартфона андроид

Блоки операторов

Как и в случае с лямбдами, стрелка может указывать либо на один оператор (как выше), либо на блок, выделенный фигурными скобками:

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

В случае, если вам показался необычным способ выхода из блоков с помощью break , а не через return , то не переживайте — меня это тоже озадачило и показалось странным. Но потом я задумался и пришел к выводу, что это имеет смысл, поскольку сохраняет старый стиль конструкции switch , которая использует break без значений.

Подробнее о выражениях switch

И последнее, но не менее важное — особенности использования switch в качестве выражения:

  • множественные выражения;
  • ранний возврат (досрочный return );
  • охват всех значений.

Обратите внимание, что при этом не имеет значения, какая форма используется!

Множественные выражения

Switch-выражения являются множественными выражениями. Это означает, что они не имеют своего собственного типа, но могут быть одним из нескольких типов. Наиболее часто в качестве таких выражений используются лямбда-выражения: s -> s + » » , могут быть Function , но также могут быть Function или UnaryOperator .

С помощью switch-выражений тип определяется по взаимодействию между тем, где используется switch и типами его веток. Если switch-выражение назначается типизированной переменной, передается в качестве аргумента или иным образом используется в контексте, где известен точный тип (это называется целевым типом), то все его ветки должны соответствовать этому типу. Вот что мы делали до сих пор:

Как итог — switch присваивается переменной result типа String . Следовательно, String является целевым типом, и все ветки должны возвращать результат типа String .

То же самое происходит и здесь:

А что произойдет сейчас?

(Про использование типа var читайте в нашей прошлой статье 26 рекомендаций по использованию типа var в Java — примечание переводчика)

Если целевой тип неизвестен, из-за того, что мы используем var, тип вычисляется путем нахождения наиболее конкретного супертипа из типов, создаваемых ветками.

Ранний возврат

Следствием различия между выражением и оператором switch является то, что вы можете использовать return для выхода из оператора switch :

… вы не можете использовать return внутри выражения …

Это имеет смысл независимо от того, используете ли вы стрелку или двоеточие.

Покрытие всех вариантов

Если вы используете switch в качестве оператора, тогда не имеет значения, охвачены все варианты или нет. Конечно, вы можете случайно пропустить case , и код будет работать неправильно, но компилятору все равно — вы, ваша IDE и ваши инструменты анализа кода останетесь с этим наедине.

Switch-выражения усугубляют эту проблему. Куда следует перейти switch , если нужная метка отсутствует? Единственный ответ, который может дать Java — это возвращать null для ссылочных типов и значение по умолчанию для примитивов. Это породило бы множество ошибок в основном коде.

Чтобы предотвратить такой исход, компилятор может помочь вам. Для switch-выражений компилятор будет настаивать, чтобы все возможные варианты были охвачены. Давайте посмотрим на пример, который может привести к ошибке компиляции:

Интересным является следующее решение: добавление ветки default , конечно, исправит ошибку, но это не является единственным решением — еще можно добавить case для FALSE .

Да, компилятор наконец-то сможет определить, охватываются ли все значения enum (исчерпывают ли все варианты), и не установить бесполезные значения по умолчанию! Давайте посидим минуту в безмолвной благодарности.

Хотя, это все же вызывает один вопрос. Что делать, если кто-то возьмет и превратит сумасшедший Bool в кватернионный Boolean, добавив четвертое значение? Если вы перекомпилируете switch-выражение для расширенного Bool, то получите ошибку компиляции (выражение больше не является исчерпывающим). Без перекомпиляции это превратится в проблему во время выполнения. Чтобы отловить эту проблему, компилятор переходит в ветку default , которая ведет себя так же, как та, которую мы использовали до сих пор, вызывая исключение.

В Java 12 охват всех значений без ветки default работает только для enum , но когда switch в будущих версиях Java станет более мощным, он также сможет работать с произвольными типами. Если метки case ‘ов смогут не только проверять равенство, но и проводить сравнения (например _ …) — это позволит охватить все варианты для числовых типов.

Размышление

Из статьи мы узнали, что Java 12 превращает switch в выражение, наделяя его новыми возможностями:

  • теперь один case может соответствовать нескольким меткам;
  • новая стрелочная форма case … -> … следует синтаксису лямбда-выражений:
    • допускаются однострочные операторы или блоки;
    • предотвращается сквозной переход к следующему case ;
  • теперь всё выражение оценивается, как значение, которое затем может быть присвоено переменной или передано, как часть более крупного оператора;
  • множественное выражение: если целевой тип известен, то все ветки должны ему соответствовать. В противном случае определяется конкретный тип, который соответствует всем веткам;
  • break может возвращать значение из блока;
  • для выражения switch использующее enum , компилятор проверяет охват всех его значений. Если default отсутствует, добавляется ветка, которая вызывает исключение.

Куда это нас приведет? Во-первых, поскольку это не окончательная версия switch , у вас все еще есть время, чтобы оставить отзыв в списке рассылки Amber, если вы с чем-то не согласны.

Затем, предполагая, что switch остается таким, каким он является в данный момент, я думаю, что стрелочная форма станет новым вариантом по умолчанию. Без сквозного перехода к следующему case и с лаконичными лямбда-выражениями (это очень естественно иметь case и один оператор в одной строке) switch выглядит намного компактнее и не ухудшает читаемость кода. Я уверен, что буду использовать только двоеточие, если у меня возникнет необходимость в сквозном проходе.

Что вы думаете? Довольны тем, как все сложилось?

Источник

Оцените статью