switch 表达式可以写成两种不同的方式:使用冒号 (:
) 或箭头 (->
)。箭头在 Java 12 中首次引入,并在 Java 14 中正式添加。在之前的教程中,我解释了 Java 的 switch 语句。假设你已经对 switch 语句很熟悉。如果不熟悉,请参考我之前的教程。在这里可以找到链接。
让我们来区分switch
语句和switch
表达式。主要的区别在于switch
表达式会返回一个值,而switch
语句则不会。可以说,switch
表达式相当于一个可以返回值的增强版switch
语句。
(注释:根据具体上下文,"yield" 可进一步明确为 "产量" 或其他领域特定术语,此处保留“收益”以适应多种可能的语境。)
在开始之前,我想先介绍一个新的上下文关键字 yield
。你可以把它想象成在 switch 语句中的 break
,但功能更强大。它只能用在 switch 表达式里。虽然 yield
不是一个真正的关键字,但在 switch 表达式的上下文中,它却有着特殊的含义。
表达式中的冒号用法和 switch 语句中的差不多。我们来看个例子。
定义一个整型变量selectorExpression1
并赋值为1:
根据selectorExpression1
的值,定义一个字符串变量message
:
当selectorExpression1
的值为1时:
返回字符串'#1'
:
其他情况下:
抛出一个新的异常,说明遇到了未预料到的值,变量的值为selectorExpression1
;
打印输出message
变量的值。
需要注意的几点如下:
- 由于它是一个表达式,后面必须跟一个分号。
- switch 表达式不能有空的代码块。
// 这不会编译
// int selectorExpression2 = 1
// String message2 = switch (selectorExpression1) {}; // switch 语句需要一个表达式作为参数
可以使用代码块的形式,但 yield
语句必须作为最后一行代码出现。
int selectorExpression3 = 1;
String message3 = switch (selectorExpression3) {
case 1:
// 返回 "#1"; 但无法编译
System.out.println("选择表达式3 = " + selectorExpression3);
yield "#1"; // `yield` 关键字在这里表示返回或输出一个值
default:
throw new IllegalStateException("意外的值: " + selectorExpression3);
};
System.out.println("message3 = " + message3);
- 开关语句必须包含默认分支,因此它必须包含所有可能的情况。
// 无法编译通过
// int selectorExpression4 = 1;
// String message4 = switch (selectorExpression4) {
// case 1:
// yield "#1";
// };
- 除非这是一个枚举,并且所有值都被用到了,否则删除任何值会导致编译失败,并会要求缺失的值或默认标签。
枚举类型 Day {
星期日, 星期一, 星期二, 星期三, 星期四, 星期五, 星期六
}
Day day = Day.星期日;
String message5 = switch (day) {
case 星期六:
case 星期日:
返回 "休息日";
case 星期一:
case 星期二:
case 星期三:
case 星期四:
case 星期五:
返回 "工作日";
};
打印消息5 = " + message5;
- 如果我们使用
yield
,就必须将结果赋值给一个变量,否则会导致编译错误。
# 以下是一个使用yield的函数示例
def example_function():
yield 42
# 直接打印结果
result = example_function()
print(result) # 你将看到的是生成器对象,而不是具体的数值
// 无法编译,会报错
// int selectorExpression6 = 1;
// switch (selectorExpression6) {
// case 1:
// yield "#1"; // 返回 '#1'
// default:
// throw new IllegalStateException("意外的值:" + selectorExpression6);
// };
- 我们不能在 switch 表达式中使用
break
或return
。 - 虽然执行顺序与 switch 语句类似,但在这里我们使用 yield 替代了 break 或 return。
int selectorExpression7 = 1; // 选择表达式初始化为1
String message7 = switch (selectorExpression7) { // 根据选择表达式的值进行switch判断
case 1, 2, 3: // 如果选择表达式的值为1, 2, 或3
// 返回字符串 "<=3",yield在Java中表示生成一个值
yield "<=3";
case 4, 5: // 如果选择表达式的值为4或5
case 6: // 或者为6
// 返回字符串 ">=3"
yield ">=3";
default: // 如果选择表达式的值不在上述范围内
// 抛出一个非法状态异常,表示接收到一个意外的值
throw new IllegalStateException("意外的值: " + selectorExpression7); // 输出异常信息,提示意外的值
};
// 输出message7的值,解释该行代码的作用
System.out.println("message7 = " + message7); // 输出结果为message7等于返回的字符串
- 我们可以使用传统的方法来添加常数,每个标签指定一个常数,或者在一个标签中添加它们,并用逗号隔开。参见之前的代码片段。
带有箭头标注的开关表达式类似于switch语句,只不过它的执行必须返回一个值或必须抛出一个异常。
int selectorExpression8 = 1;
String message8 = switch (selectorExpression8) {
case 1 -> "#1";
// case 2 -> yield "#2"; // 此行代码无法编译
default -> throw new IllegalStateException("抛出异常:意外的值: " + selectorExpression8);
};
System.out.println("message = " + message8);
如果与标签相关的表达式只有一行,不需要也不可以使用 yield
。每个标签可以关联一个代码块。在这种情况下,yield
必须放在代码块的最后一行。
int selectorExpression9 = 1;
String message9 = switch (selectorExpression9) {
case 1 -> {
// 生成 "#1"; // 编译不过
System.out.println("selectorExpression9 = " + selectorExpression9);
yield "#1";
}
default -> throw new IllegalStateException("未知的值: " + selectorExpression9);
};
System.out.println("message = " + message9);
没有真正的失败执行,并且开关表达式必须覆盖所有情况;这可以通过添加默认标签来实现。
您可以在这里看到该项目的完整版本:
通过在 GitHub 上创建账户来参与 polovyivan/java-switch-expression 的开发 结论部分这结束了我们对Java switch构造探索的第二部分。自Java 8以来,switch语句已经有了很大的改进。本教程旨在帮助你学习或更新有关的知识,通过可以在你的电脑上运行的实际代码示例。
谢谢阅读!如果您喜欢这篇文章,请点赞并关注我。如果您有任何问题或建议,欢迎在评论区留言或通过LinkedIn与我联系 我的LinkedIn。
共同學(xué)習(xí),寫下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章