当编写带有很多条件的代码时,您肯定使用过if-elseswitch语句。但是这种替代if-else的方法有缺点。有些人甚至称switch语句为“反模式”。

那是什么?反模式是错误代码的常见模式,即问题的错误解决方案。程序员试图在代码中避免它们,因为它们会降低代码质量。

但有个好消息:新版本的 Java 对该语言的语法进行了大量更改,其中一项更改会影响switch。感兴趣吗?那么让我们开始吧。

首先,有必要澄清一下为什么switch是一种反模式。考虑以下代码:


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    default:
        seasonNumber = 0;
}

好的,所以目前还不完全清楚为什么这是一个“反模式”。

但是如果我们添加更多的case块,现在代码看起来像这样:


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    case “MARCH”:
        seasonNumber = 2;
        break;
    case “APRIL”:
        seasonNumber = 2;
        break;
    case “MAY”:
        seasonNumber = 2;
        break;
    default:
        seasonNumber = 0;
}

让我们再添加几行——代码变长了。以后我们可以添加越来越多的行,没有人会阻止我们这样做。

这就是问题的核心所在:在最初创建一个紧凑的switch语句后,我们向其中添加了越来越多的代码,占用了越来越多的空间——超过了屏幕上的空间——并且使代码不便于阅读和维护。

switch语句和switch表达式的区别

Java 14 引入了一个新的和改进的开关。它不是switch 语句,而是switch 表达式

你问有什么区别?不同之处在于,语句是执行一组特定操作的指令,而表达式是执行某些计算并返回结果的一段代码。

换句话说,现在您可以将切换的结果保存到变量中。

说够了。现在让我们看看新开关的样子:


var result = switch(month) {
     case DECEMBER, JANUARY, FEBRUARY -> 1;
     case MARCH, APRIL, MAY -> 2;
    case JUNE, JULY, AUGUST -> 3;
    case SEPTEMBER, OCTOBER, NOVEMBER -> 4;
    default -> 0; 
};

首先引起您注意的是代码的紧凑程度。过去占据大部分屏幕的代码现在只需要几行,看起来更易读。

-> 运营商

您还应该注意->运算符(箭头运算符)。如果您有使用 lambda 表达式的经验,您可能已经熟悉它。

这意味着现在您可以用 lambda 语句的样式编写一个看起来很酷的开关。箭头运算符表示编译器不会继续执行下一个case表达式(如果当前case 块缺少breakreturn语句),而是会为您提供箭头右侧的表达式的值。

您还可以编写不是表达式的代码,只执行某些操作而不返回任何内容:


switch(condition) {
    case TRUE, FALSE -> System.out.println("True/false");
  
    default -> System.out.println("Another");
}

请注意,switch不再有break语句。它在 Java 13 中被删除并被yield取代。

什么是 yield 以及它可以用在什么地方?

开关由单行组成时,->运算符本身会返回值。但是,如果我们没有一行代码,而是多行代码怎么办?在这种情况下,箭头运算符不会返回值,因为有多行,而不是一行。

也许我们可以使用return?毕竟,它是用来在 Java 中返回值的。las,不,return不能与 switch 一起使用。那我们可以用什么呢?以前有break,但在 Java 13 中被删除了。但是现在我们有了yield取而代之——一个新的关键字,可以帮助您从开关返回一个值。它类似于方法中的return语句。


var result = switch(condition) {
//…
case "Hi" -> "greeting"
//…
};  

此代码包含一行,->运算符将返回“greeting”。

但是当我们有一段代码时:


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 Here you need to return "greeting"
	}
};  

帮助您返回值的关键字是yield


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 yield "greeting";

	}
};

yield是在 Java 13 中添加的,用于处理 case 块中有多行代码并且需要返回结果的情况。

您可能急于在代码中尝试新的开关,但请记住,您需要 Java 14 或更高版本才能执行此操作。对于早期版本,此开关仅在您在命令行中指定“--enable-preview”标志时可用,因为在版本 14 之前它是技术预览的一部分,而不是语言的完整部分。

目前为止就这样了!再见!