为啥 Switch 需要语句但接受表达式
Posted
技术标签:
【中文标题】为啥 Switch 需要语句但接受表达式【英文标题】:Why Switch requires statement but accepts expressions为什么 Switch 需要语句但接受表达式 【发布时间】:2021-12-26 07:02:26 【问题描述】:我正在研究 switch 表达式,我想我发现了一个奇怪的行为:
public static boolean isTimeToParty(Day day)
switch (day)
case MONDAY -> dog(); //expression allowed
case TUESDAY -> 2 + 2; //error: not a statement
case WEDNESDAY -> true; //error: not a statement
default -> System.out.println("");
return false;
public static int dog()
return 2;
为什么我可以键入值dog()
这是一个表达式,但不允许使用其他类型的表达式? Intellij 提示我 "not a statement"
错误。
提前致谢。
【问题讨论】:
【参考方案1】:根据语言规范,方法调用表达式也可以用作语句:
14.8. Expression Statements
某些类型的表达式可以用作语句,如下所示 他们用分号。 表达式语句: 语句表达式; StatementExpression: 赋值 PreIncrementExpression PreDecrementExpression PostIncrementExpression PostDecrementExpression MethodInvocation ClassInstanceCreationExpression
倒数第二行表示可以将方法调用表达式用作语句,这就是接受dog()
的原因。返回值被简单地丢弃。 2 + 2
不能用作语句。
【讨论】:
【参考方案2】:IntelliJ 识别出您正在尝试使用 switch 语句而不是 switch 表达式。如果您将代码更改为:
int val = switch (day)
case MONDAY -> dog();
case TUESDAY -> 2 + 2;
case WEDNESDAY -> true;
default -> System.out.println("");
您会发现错误现在与 print 语句和 true
值有关,因为它们无法转换为 int
。这是因为 Intellij 现在将您的代码识别为 switch 表达式。
换句话说,switch 表达式的所有分支都必须是相同类型的表达式,switch 语句的分支必须是语句。方法调用dog()
是两者,因此它可以在任一上下文中工作。
【讨论】:
【参考方案3】:问题是2 + 2
和true
不是Java 语句。在reference documentation 中我们可以看到以下内容:
语句大致相当于自然语言中的句子。一种 语句形成一个完整的执行单元。以下类型 表达式可以通过终止表达式变成语句 用分号 (;)。
赋值表达式 任何使用 ++ 或 -- 方法调用 对象创建表达式这样的语句称为表达式语句。这里有一些 表达式语句示例:
// 赋值语句 aValue = 8933.234;
// 递增语句 一个值++;
// 方法调用语句 System.out.println("Hello World!");
//对象创建语句 自行车 myBike = new Bicycle();
2 + 2
和 true
不是这些,因为它们是表达式,因此您的 switch 语句中会出现编译错误。
【讨论】:
switch 表达式中允许使用 -> 语法, 我不是说不是。我只是说2 + 2
和 true
不是语句,因此不允许在 switch 语句中。【参考方案4】:
开关在语句上下文中。一个语句也可能是一个方法调用,丢弃它的结果。还存在switch表达式,要求颠倒。
【讨论】:
以上是关于为啥 Switch 需要语句但接受表达式的主要内容,如果未能解决你的问题,请参考以下文章