Конструкция switch/case оценивает некоторое выражение и сравнивает его значение с набором значений. И при совпадении значений выполняет определенный код.
Конструкция switch/case в некоторой степени аналогична конструкции if/else, так как позволяет обработать сразу несколько условий.
В классическом виде конструкция switch имеет следующее формальное определение:
switch (выражение)
{
case значение1:
код,выполняемый если выражение имеет значение1
break;
case значение2:
код,выполняемый если выражение имеет значение2
break;
//.............
case значениеN:
код, выполняемый если выражение имеет значениеN
break;
default:
код, выполняемый если выражение не имеет ни одно из выше указанных значений
break;
}
После ключевого слова switch в скобках идет сравниваемое выражение. Значение этого выражения последовательно сравнивается со значениями, помещенными после оператора сase. И если совпадение будет найдено, то будет выполняться определенный блок сase.
В конце каждого блока сase должен ставиться один из операторов перехода:
break, return или throw.
Как правило, используется оператор break. При его применении другие блоки case выполняться не будут.
Например:
class Program {
public static void main(String[] args) {
String name = "Tom";
switch (name){
case "Bob":
System.out.println("Ваше имя - Bob");
break;
case "Tom":
System.out.println("Ваше имя - Tom");
break;
case "Sam":
System.out.println("Ваше имя - Sam");
break;
}
}
}
В данном случае конструкция switch последовательно сравнивает значение переменной name с набором значений,
которые указаны после операторов case. Поскольку здесь значение переменной name - строка "Tom", то будет выполняться блок
case "Tom":
System.out.println("Ваше имя - Tom");
break;
Соответственно мы увидим на консоли
Ваше имя - Tom
Если бы мы не использовали бы в данном случае операторы break, как в следующем случае:
String name = "Tom";
switch (name){
case "Bob":
System.out.println("Ваше имя - Bob");
case "Tom":
System.out.println("Ваше имя - Tom");
case "Sam":
System.out.println("Ваше имя - Sam");
}
То после выполнения блока
case "Tom":
System.out.println("Ваше имя - Tom");
Стал бы выполняться блок
case "Sam": System.out.println("Ваше имя - Sam");И мы бы получили следующий консольный вывод:
Ваше имя - Tom Ваше имя - Sam
Если значение переменной name не совпадает ни с каким значением после операторов case, то ни один из блоков case не выполняется.
Однако если даже в этом случае нам все равно надо выполнить какие-нибудь действия, то мы можем добавить в конструкцию switch необязательный
блок default. Например:
string name = "Alex";
switch (name)
{
case "Bob":
System.out.println("Ваше имя - Bob");
break;
case "Tom":
System.out.println("Ваше имя - Tom");
break;
case "Sam":
System.out.println("Ваше имя - Sam");
break;
default:
System.out.println("Неизвестное имя");
break;
}
В данном случае никакое из значений после операторов case не совпадает со значением переменной name, поэтому будет выполняться блок default:
default:
System.out.println("Неизвестное имя");
break;
В классической версии конструкции switch каждый блок case, если мы хотим закончить на нем выполнение, завершается оператором break. И обычно так и есть, редко когда требуется выполнять
другие блоки case. И поэтому в результате развития Java в язык была добавлена новая форма конструкции switch:
switch (выражение)
{
case значение1 ->
код,выполняемый если выражение имеет значение1
case значение2 ->
код,выполняемый если выражение имеет значение2
//.............
case значениеN ->
код, выполняемый если выражение имеет значениеN
default ->
код, выполняемый если выражение не имеет ни одно из выше указанных значений
}
В данной форме блок default также необязателен. Например, перепишем первый пример из текущей статьи:
class Program {
public static void main(String[] args) {
String name = "Tom";
switch (name){
case "Bob" -> System.out.println("Ваше имя - Bob");
case "Tom" -> System.out.println("Ваше имя - Tom");
case "Sam" -> System.out.println("Ваше имя - Sam");
}
}
}
Если в блок case надо поместить несколько инструкций или более сложный код, то он оформляется в блок кода:
case "Tom" -> {
System.out.println("Ваше имя - Tom");
System.out.println("Привет, Tom");
}
Ключевое слово switch также применяется для создания выражения switch, которое позволяет возвращать некоторое значение - то есть получить результат выполнения конструкции switch.
Для возвращения значения в блоках case может применятся
оператор return. Например, определим следующую программу:
class Program {
public static void main(String[] args) {
int operation = 1; // выполняемая операция
int a = 10, b = 6; // числа, над которыми выполняется операция
int result = 0; // результат операции
switch (operation)
{
case 1:
result = a + b;
break;
case 2:
result = a - b;
break;
case 3:
result = a * b;
break;
default:
result = 0;
}
System.out.println(result); // 16
}
}
Здесь у нас есть номер операции - переменная operation, два числа для выполнения операции - a и b и переменная result для хранения результата операции. В конструкции switch в зависимости от номера операции присваиваем переменной result соответствующее значение.
С помощью новой формы конструкции switch мы можем слегка упростить код:
class Program {
public static void main(String[] args) {
int operation = 1; // выполняемая операция
int a = 10, b = 6; // числа, над которыми выполняется операция
int result = 0; // результат операции
switch (operation)
{
case 1 -> result = a + b;
case 2 -> result = a - b;
case 3 -> result = a * b;
default -> result = 0;
}
System.out.println(result); // 16
}
}
Тем не менее ключевым моментом в данном случае, является то, что во всех случаях нам надо установить переменную result - передать ей нужный результат операции над числами. И выражения switch
позволяют упростить эту задачу:
class Program {
public static void main(String[] args) {
int operation = 1; // выполняемая операция
int a = 10, b = 6; // числа, над которыми выполняется операция
// результат операции
int result = switch (operation)
{
case 1 -> a + b;
case 2 -> a - b;
case 3 -> a * b;
default -> 0;
}; // в конце обязательна точка с запятой
System.out.println(result); // 16
}
}
В данном случае мы напрямую присваиваем переменной result то значение, которое вычисляет выражение switch. Вычисляемое значение ставится после стрелки в блоке case
case 1 -> a + b;
Благодаря этому код стал проще и понятнее.
Но, следует отметить, что блоки case должны охватывать все потенциальные значения. Например, в данном случае случае мы получаем значение в переменную result - переменную типа int.
Тип int охватывает 322 значений. Естественно в данном случае для каждого из них определять свой блок case нерационально, тем более нам нужны только три значения - для каждой операции.
И в этом случае для всех остальных значений применяется выражение default, которое в данном случае просто возвращает 0.
Если же нам надо выполнить несколько инструкций в каждом блоке case, то инструкции оформляются в отдельный блок кода:
class Program {
public static void main(String[] args) {
int operation = 1; // выполняемая операция
int a = 10, b = 6; // числа, над которыми выполняется операция
// результат операции
int result = switch (operation)
{
case 1 -> {
System.out.println("a + b");
yield a + b;
}
case 2 -> {
System.out.println("a - b");
yield a - b;
}
case 3 -> {
System.out.println("a * b");
yield a * b;
}
default -> 0;
};
System.out.println(result); // 16
}
}
При этом для возвращения значения из блока кода применяется оператор yield, после которого ставится возвращаемое значение:
yield a - b;
Стоит отметить, что также существует другая форма выражения switch, где после операторов case ставится двоеточие:
class Program {
public static void main(String[] args) {
int operation = 1; // выполняемая операция
int a = 10, b = 6; // числа, над которыми выполняется операция
// результат операции
int result = switch (operation)
{
case 1:
System.out.println("a + b");
yield a + b;
case 2:
System.out.println("a - b");
yield a - b;
case 3:
System.out.println("a * b");
yield a * b;
default: yield 0;
};
System.out.println(result); // 16
}
}
Но в этом случае в конце блока case надо обязательно использовать оператор yield для возвращения значения