Switch表达式


Switch表达式

Java14

提供了新的switch语法,即:

switch的分支结果可以直接作为返回结果给到前面的变量,或是在后续课程中用做方法返回值使用:

int score = 9;
//直接让res接收switch的结果
char res = switch(score){
	case 10,9 -> 'A';
	case 8 -> 'B';
	case 7,6 -> 'C';
	default -> 'D';
};       //注意这是一个赋值语句,后面要加分号
sout(res);

即switch有了返回值,变量需要接收,switch语句中的冒号,break等也不在了,取而代之的是箭头。

当然,如果除了返回值外,还需要执行别的操作,可以写成代码块的形式,此时要用到关键字 yield,表示延迟返回:

int score = 9;
char res = switch(score){
	case 10,9 -> 'A';
	case 8 -> 'B';
	case 7,6 -> 'C';
	default -> {
		sout("不及格");
		yield 'D';   //指定延迟返回的结果,并自动结束分支
};
sout(res);

switch模式匹配(Java21后)

即switch除了可以根据变量的不同值做出判断外,增加了一个新功能:判断变量类型(只能是引用类型,Java25之后可以是基本类型)

public static void tellInstance(Object obj){
       String type = switch (obj){
          case Integer i -> "Integer";   //i和s为定义的返回值的变量名
          case String s -> "String";
          case null -> "Null";  //null和default直接加箭头
          default -> "Other";        
       };  //记得每个语句和最后加分号
      System.out.println(type);
   }

我们注意到,模式匹配中的类型后面必须跟一个变量名字,能否有一种办法省略掉呢?在Java 22之后,我们可以使用_下划线来直接取代,表示这是一个后续不会使用的未命名的变量

如果除了判断类型,我们还想判断别的,可以使用 when 关键字,在后面加上想要额外判断的条件进行额外条件检查,这种操作称为”守卫条件”

when后面需要填写判断条件,和if一样,必须为一个返回值为boolean的表达式,也可以使用与或非操作

这样,在switch中也可以实现区间判断

public static void tellGrade(Integer score){
      String type = switch(score){
         case Integer i when score >= 90 -> "A";
         case Integer i when score >= 80 -> "B";
         case Integer i when score >= 60 -> "C";
         default -> "D";
      };
      System.out.println(type);
   }

记录类型

此外,针对于此前提到的记录类型,在switch语句中支持直接解构使用:

record Point(int x, int y) {}

public static Integer test(Object object) {
    return switch (object) {
        case Point(int x, int y) -> x + y;  //直接解构其参数使用
        case String _ -> 10;
        default -> 5;
    };
}

这里针对于记录类型,类似重新写了一次类型声明,编写完整的类名加参数Point(int x, int y)表示当object如果是记录类型,则进入此分支且解构其内部成员变量,这里写的xy作为结构出来的变量可以直接在后续使用。同样的,解构的变量如果后续不使用也可以直接使用下划线代替。

	return switch (object) {
    case Point(int _, int y) -> y;
    case String _ -> 10;
    default -> 5;
};

switch还支持对记录类内部成员的类型嵌套匹配:

record Container(Object data) {}  //这里data是Object类型的

public static Integer test(Container object) {
    return switch (object) {
        case Container(String str) -> str.length();  //其内部类型如果是String
        case Container(Integer i) -> i;  //其内部类型如果是Integer
        default -> 0;
    };
}

Author: havenochoice
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source havenochoice !
评论
  TOC