3

我正在研究 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"错误。

提前致谢。

4

4 回答 4

3

根据语言规范,方法调用表达式也可以用作语句:

14.8. 表达式语句

某些类型的表达式可以通过在它们后面加上分号来用作语句。
表达式语句:
语句表达式;
StatementExpression:
赋值
PreIncrementExpression
PreDecrementExpression
PostIncrementExpression
PostDecrementExpression
MethodInvocation
ClassInstanceCreationExpression

倒数第二行表示方法调用表达式可以用作语句,这就是dog()接受的原因。返回值被简单地丢弃。2 + 2不能用作陈述。

于 2021-11-15T00:59:33.457 回答
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()是两者,因此它可以在任一上下文中工作。

于 2021-11-15T00:45:34.583 回答
0

问题是那2 + 2不是trueJava 语句。在参考文档中,我们可以阅读以下内容:

语句大致相当于自然语言中的句子。一条语句构成一个完整的执行单元。通过以分号 (;) 结束表达式,可以将以下类型的表达式组成语句。

  • 赋值表达式
  • 任何使用 ++ 或 --
  • 方法调用
  • 对象创建表达式

这样的语句称为表达式语句。以下是表达式语句的一些示例:

// 赋值语句
aValue = 8933.234;

// 递增语句
aValue++;

// 方法调用语句
System.out.println("Hello World!");

// 对象创建语句
Bicycle myBike = new Bicycle();

2 + 2并且true不是这些,因为它们是表达式,因此您的 switch 语句中的编译错误。

于 2021-11-15T00:40:05.527 回答
0

开关在语句上下文中。一个语句也可能是一个方法调用,丢弃它的结果。还存在 switch 表达式,其中的要求是相反的。

于 2021-11-15T01:47:52.123 回答