【问题标题】: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" 错误。

提前致谢。

【问题讨论】:

    标签: java switch-statement conditional-statements switch-expression


    【解决方案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 + 2true 不是Java 语句。在reference documentation 中我们可以看到以下内容:

        语句大致相当于自然语言中的句子。一种 语句形成一个完整的执行单元。以下类型 表达式可以通过终止表达式变成语句 用分号 (;)。

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

        这样的语句称为表达式语句。这里有一些 表达式语句示例:

        // 赋值语句
        aValue = 8933.234;

        // 递增语句
        一个值++;

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

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

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

        【讨论】:

        • switch 表达式中允许使用 -> 语法,
        • 我不是说不是。我只是说 2 + 2true 不是语句,因此不允许在 switch 语句中。
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2023-01-16
          • 2011-04-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-15
          • 2020-07-29
          • 1970-01-01
          相关资源
          最近更新 更多