详解Java12新增语法switch表达式
引言
在学习分支语句的时候,我们都学过 switch 语句,相比于 if-else 语句,他看起来更加整洁,逻辑更加清晰,Java中当然也给我们提了相关的 switch 方法。但是Java的强大之处在于,他对这一语句结构进行了拓展。在Java 12中,Java新引入了switch表达式Switch Expressions,我们都知道,switch 语句如果漏写一个 break,那么逻辑往往就跑偏了,这种方式既繁琐,又容易出错。那么Switch Expressions为我们提供勾勒出了Java 语法进化的一个趋势,将开发者从复杂繁琐的低层次抽象中逐渐解放出来,以更高层次更优雅的抽象,既降低代码量,又避免意外编程错误的出现,进而提高代码质量和开发效率。下面我将对传统的switch语句和switch表达式做出对比,并介绍switch表达式的用法。
对比
例如,根据用户输入的年份和月份,判断这个月一共有多少天,传统switch语句代码如下:
package day_11_25;
import java.time.LocalDate;
import java.util.Scanner;
/**
* @author soberw
*/
public class Switch {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入年份:");
int year = sc.nextInt();
System.out.print("请输入月份:");
int month = sc.nextInt();
int day = 31;
switch (month) {
case 4:
case 6:
case 9:
case 11:
day = 30;
break;
case 2:
day = (LocalDate.of(year, month, 1).isLeapYear()) ? 29 : 28;
break;
default:
break;
}
System.out.printf("%d年%d月有%d天%n", year, month, day);
}
}
运行测试:
使用switch表达式后:
package day_11_25;
import java.time.LocalDate;
import java.util.Scanner;
/**
* @author soberw
*/
public class SwitchExpression {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入年份:");
int year = sc.nextInt();
System.out.print("请输入月份:");
int month = sc.nextInt();
int day = switch (month) {
case 4, 6, 9, 11 -> 30;
case 2 -> (LocalDate.of(year, month, 1).isLeapYear()) ? 29 : 28;
default -> 31;
};
System.out.printf("%d年%d月有%d天%n", year, month, day);
}
}
运行测试:
用法分析
那么switch语句与switch表达式最大的区别就是switch可以有返回值了,这也就是为什么我用的时候可以"int day = "了,每一个分支只需要决定具体的返回值是什么,不需要考虑如何使用这个值。而全程只需要一次赋值操作。代码整体变得更简洁、紧凑、清晰。
switch表达式也可以使用 : ,在这种情况下,各个分支必须用break关键字返回值。若使用->这种形式就不需要break,但是:和->不可以混合使用
需要注意的是:
switch表达式必须有default,你可以理解为我们在声明变量的时候必须加一个默认值一样
代码块与yield关键字
那么如果我们想加入其他操作呢,比如在上面案例中,当月份是2月时,我除了想要给day赋值,我还想多输出一句“现在是二月!”那这时候就可以使用代码块了,形式如下:
package day_11_25;
import java.time.LocalDate;
import java.util.Scanner;
/**
* @author soberw
*/
public class SwitchExpression2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入年份:");
int year = sc.nextInt();
System.out.print("请输入月份:");
int month = sc.nextInt();
int day = switch (month) {
case 4, 6, 9, 11 -> 30;
case 2 -> {
//这里是代码块
System.out.println("现在是二月!");
yield (LocalDate.of(year, month, 1).isLeapYear()) ? 29 : 28;
}
default -> 31;
};
System.out.printf("%d年%d月有%d天%n", year, month, day);
}
}
运行结果:
在执行当前分支的时候,如果我们直接返回值,就可以直接写值就行了,但如果我们想在返回值之前再执行其他操作呢,那就必须使用代码块,用{}括起来,最后通过yield关键字将值返回出来就ok了
注意!!!
使用了代码块之后,{}外面一定不要加;(本人已踩坑。。。)