1. Введение
Представьте себе: вы пишете программу для кофейни. Пользователь может выбрать напиток, и вам нужно отреагировать на этот выбор. Можно, конечно, использовать кучу if-else if-else, но выглядит это не очень:
if (choice == 1)
{
System.out.println("Вы выбрали эспрессо.");
}
else if (choice == 2)
{
System.out.println("Вы выбрали капучино.");
}
else if (choice == 3)
{
System.out.println("Вы выбрали латте.");
}
else
{
System.out.println("Такого напитка нет.");
}
Согласитесь, выглядит громоздко. А если вариантов будет 10 или 20? Вот тут и приходит на помощь оператор switch, который позволяет элегантно и компактно реализовать выбор из множества вариантов по значению переменной.
Синтаксис классического switch
Синтаксис switch в Java выглядит так:
switch (выражение)
{
case значение1:
// действия, если выражение == значение1
break;
case значение2:
// действия, если выражение == значение2
break;
...
default:
// действия, если не совпало ни с одним case
break;
}
switch в Java
Ключевые элементы:
- switch (выражение) — выражение, результат которого сравнивается с каждым case.
- case значение: — вариант, с которым сравнивается выражение.
- break; — завершает выполнение блока switch (иначе — «проваливание» в следующий case).
- default: — выполняется, если не совпало ни с одним case.
2. Примеры использования switch
Пример 1: Классика жанра — выбор напитка
Давайте реализуем меню для кофейни:
import java.util.Scanner;
public class CoffeeShop
{
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
System.out.println("Выберите напиток:");
System.out.println("1 - Эспрессо");
System.out.println("2 - Капучино");
System.out.println("3 - Латте");
int choice = console.nextInt();
switch (choice)
{
case 1:
System.out.println("Вы выбрали эспрессо.");
break;
case 2:
System.out.println("Вы выбрали капучино.");
break;
case 3:
System.out.println("Вы выбрали латте.");
break;
default:
System.out.println("Такого напитка нет.");
break;
}
}
}
Что происходит:
- Пользователь вводит номер напитка.
- Значение переменной choice сравнивается с каждым case.
- Если совпало — выполняется соответствующий блок, затем break завершает выполнение switch.
- Если не совпало ни с одним — выполняется default.
Пример 2: Переключатель по строкам
Не так много типов можно использовать внутри switch, но строки — можно! Это удобно для командных меню:
import java.util.Scanner;
public class CommandMenu
{
public static void main(String[] args)
{
Scanner console = new Scanner(System.in);
System.out.println("Введите команду (start, stop, pause):");
String command = console.nextLine();
switch (command)
{
case "start":
System.out.println("Запуск программы!");
break;
case "stop":
System.out.println("Остановка программы.");
break;
case "pause":
System.out.println("Пауза.");
break;
default:
System.out.println("Неизвестная команда.");
break;
}
}
}
Обратите внимание: сравнение строк в switch — чувствительно к регистру! "Start" и "start" — разные строки.
3. Какие типы поддерживает классический switch?
В классическом switch можно использовать только определённые типы:
- Примитивные целочисленные типы: byte, short, char, int
- Перечисления: enum (о них поговорим на следующей лекции)
- Строки: String — сравниваются с учётом регистра
Нельзя использовать: boolean, float, double, массивы, произвольные объекты классов (кроме enum и String).
Пример с char
char grade = 'B';
switch (grade)
{
case 'A':
System.out.println("Отлично!");
break;
case 'B':
System.out.println("Хорошо.");
break;
case 'C':
System.out.println("Удовлетворительно.");
break;
default:
System.out.println("Попробуйте ещё раз.");
break;
}
4. Обязательность break: что будет, если забыть?
Самая частая ошибка новичков — забыть break;. Давайте посмотрим, что произойдёт:
int day = 2;
switch (day)
{
case 1:
System.out.println("Понедельник");
break;
case 2:
System.out.println("Вторник");
case 3:
System.out.println("Среда");
break;
default:
System.out.println("Неизвестный день");
break;
}
Результат:
Вторник
Среда
Почему? Потому что после case 2 нет break, и выполнение «проваливается» в следующий case (это называется fall-through). Иногда это полезно, но чаще всего — ошибка.
5. Группировка case: когда несколько вариантов ведут себя одинаково
Если для нескольких значений нужно одно и то же поведение, можно написать их подряд:
int month = 1;
switch (month)
{
case 12:
case 1:
case 2:
System.out.println("Зима");
break;
case 3:
case 4:
case 5:
System.out.println("Весна");
break;
case 6:
case 7:
case 8:
System.out.println("Лето");
break;
case 9:
case 10:
case 11:
System.out.println("Осень");
break;
default:
System.out.println("Неизвестный месяц");
break;
}
Здесь: если month — 12, 1 или 2, программа выведет "Зима".
6. Сравнение: switch и if-else
| Сценарий | if-else | switch |
|---|---|---|
| Много вариантов | Длинная цепочка, хуже читается | Кратко, все варианты видны сразу |
| Сравнение диапазонов | Можно использовать (if (x > 5 && x < 10)) | Нельзя, только конкретные значения |
| Поддерживаемые типы | Любые | Только определённые (см. выше) |
| Ловушка с break | Нет | Да, обязательно следить за break |
7. Типичные ошибки при работе с switch
Ошибка №1: забыли break
Самая частая причина багов: забыли break — и код выполняет не тот case, что вы ожидали.
Ошибка №2: неподдерживаемый тип
Пытаетесь использовать double, float или boolean — компилятор скажет «нельзя».
Ошибка №3: строки с разным регистром
Пользователь ввёл "Start", а вы ждёте "start" — switch не сработает. Лучше приводить строки к одному регистру заранее:
switch (command.toLowerCase())
{
case "start":
// ...
}
Ошибка №4: переменная в case, а не константа
Только константы разрешены в case. Если использовать переменную — будет ошибка компиляции.
Ошибка №5: дублирующие case
Два одинаковых значения case — компилятор не простит.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ