Jdk17的switch语法居然这么酷炫!

759 阅读4分钟

自 Java 7 以来,Java 中的 Switch 语句经历了非常巨大的演变。因此,在这篇文章中,来深入探讨从 Java 7 到 Java 17 的 Switch 语句的变化,并提供代码实例进行说明。

让我们从最初的 Java 7 开始吧!

Java7: switch语句

直到Java7的很长一段时间, swith-case中只能用整数:

int v = 5;
switch (v) {
    case 1:
        System.out.println("1!");
        break;
    case 5:
        System.out.println("5!");
        break;
    default:
        System.out.println("err");
}

Java8: switch语句

Java8里可以使用字符串和枚举了. 如下是String的例子:

enum DAYS {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
DAYS days = DAYS.SUNDAY;
switch (days) {
    case MONDAY:
        System.out.println("Weekdays");
        break;
    case TUESDAY:
        System.out.println("Weekdays");
        break;
    case WEDNESDAY:
        System.out.println("Weekdays");
        break;
    case THURSDAY:
        System.out.println("Weekdays");
        break;
    case FRIDAY:
        System.out.println("Weekdays");
        break;
    case SATURDAY:
        System.out.println("Weekends");
        break;
    case SUNDAY:
        System.out.println("Weekends");
        break;
    default:
        System.out.println("Unknown");
}

如下是枚举的例子:

enum DAYS {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}DAYS days = DAYS.SUNDAY;
switch (days) {
    case MONDAY:
        System.out.println("Weekdays");
        break;
    case TUESDAY:
        System.out.println("Weekdays");
        break;
    case WEDNESDAY:
        System.out.println("Weekdays");
        break;
    case THURSDAY:
        System.out.println("Weekdays");
        break;
    case FRIDAY:
        System.out.println("Weekdays");
        break;
    case SATURDAY:
        System.out.println("Weekends");
        break;
    case SUNDAY:
        System.out.println("Weekends");
        break;
    default:
        System.out.println("Unknown");
}

Java12: switch表达式

Java12进一步增强了switch表达式并且引入了一些preview feature(预览特性):

  • 可以将switch块作为一个表达式(expressions)返回一个值, 这样这个switch块就是一个switch表达式.
  • 在一个case中可以匹配多个值.
  • 可以在switch表达式中通过"->"操作符或者通过"break"关键字返回一个值.

通过break关键字返回一个值

return  switch (day) {
    case "Monday":
        break "Weekday";
    case "Tuesday":
        break "Weekday";
    case "Wednesday":
        break "Weekday";
    case "Thursday":
        break "Weekday";
    case "Friday":
        break "Weekday";
    case "Saturday":
        break "Weekend";
    case "Sunday":
        break "Weekend";
    default:
        break "Unknown";
};

break可以用来返回结果值.

在之后的Java13中被替换为"yield"关键字.

return  switch (day) {
    case "Monday":
        yield  "Weekday";
    case "Tuesday":
        yield "Weekday";
    case "Wednesday":
        yield "Weekday";
    case "Thursday":
        yield "Weekday";
    case "Friday":
        yield "Weekday";
    case "Saturday":
        yield "Weekend";
    case "Sunday":
        yield "Weekend";
    default:
        yield "Unknown";
};

通过箭头操作符返回值:

return  switch (day) {
            case "Monday"-> "Week day";
            case "Tuesday"-> "Week day";
            case "Wednesday"->"Week day";
            case "Thursday"->"Week day";
            case "Friday"->"Week day";
            case "Saturday"-> "Weekend";
            case "Sunday"-> "Weekend";
            default->"Unknown";
        };

case匹配多个值: Java12开始case可以匹配多个值了, 在上面的例子中可以看到星期一到星期五都是返回相同的值, 而你就可以用一个case匹配星期一到星期五而不需要重复写相同的返回值五次:

return  switch (day) {
            case "Monday","Tuesday","Wednesday","Thursday","Friday"
-> "Week day";
            case "Saturday", "Sunday" -> "Weekend";
            default->"Unknown";
        };

Java 14 : switch语句变更

到目前为止,我们在java 12和13中讨论的任何开关语句和特性都是预览特性,需要将flag -enable-preview设置为true。 Java 14只是将所有的功能从预览功能永久保留下来 从java 14开始,不需要设置flag -enable-preview就能启用上述特性.

Java 17 : Switch语句

Java 17 LTS于2021年9月15日发布, 是一个长期支持版本.它包含的Switch语句特性如下:

  • Pattern matching模式匹配
  • Gaurded pattern
  • 支持case null

我们一个个的看:

Pattern Matching

你可以在case中匹配一个pattern, 这有点抽象, 换句话说你可以在case中传入Object, 并且可以在switch case标签中检查该对象的不同类型。

return switch (obj) {
    case Integer i -> "It is an integer";
    case String s -> "It is a string";
    case Employee s -> "It is a Employee";
     default -> "It is none of the known data types";
};

在上面的例子中,我传递了一个对象给switch条件。这在Java 17之前是不可能实现的。然后可以检查这个对象是否为特定的数据类型,并将其赋值给一个变量。

case Integer i- > "It is an integer";

检查传入的对象是否为“Integer”类型,如果是整数,则将其赋值给变量“i”。通过箭头操作符返回字符串“It is an integer”。

Gaurded Patterns

让我们以这个用例为例。

在case标签中已经检查了“Employee”实例,现在想做一个额外的检查。

按照以往的做法,只能在case之后做这个校验。

像这样:

case Employee emp:

if(emp.getDept().equals("IT")) {

yield "This is IT Employee";

}

但是这个“Gaurded Patterns”特性可以在case标签中就进行这个检查,如下所示:

return switch (obj) {
    case Integer i -> "It is an integer";
    case String s -> "It is a string";
    case Employee employee && employee.getDept().equals("IT") -> "IT Employee";
    default -> "It is none of the known data types";
};

Null Cases

在Java 17之前,给switch语句传递null值会抛出空指针异常。

Java 17之后可以这样处理:

case null -> "It is a null object";

用上面的表达式, 传递的对象即使Null也不会抛出空指针异常。

以上就是从java 7到java 17的switch的变化。希望你喜欢这篇文章,给我一个赞吧!