了解 Java 的 switch 表达式

提到 switch, 所有 Java 开发人员应该都不陌生。switch 根据变量的值来执行不同的逻辑,用来替代多分支的if/else

不过 switch 语句在使用时存在一些常见问题。

首先是 switch 语句中的 case 分支的执行,默认是往下进行的,需要添加 break 来跳出 switch 的执行。这种行为很容易产生bug。比如,下面代码中的 trafficControl 方法,在参数值是 RED 时,会执行全部的 case 分支,因为并没有添加 break 语句。

public class SwitchStatement {

  enum TrafficColor {
    RED, YELLOW, GREEN
  }

  public void trafficControl(TrafficColor color) {
    switch (color) {
      case RED:
        this.stop();
      case GREEN:
        this.go();
      default:
        this.watchOut();
    }
  }

  private void go() {
    System.out.println("Go!");
  }

  private void stop() {
    System.out.println("Stop!");
  }

  private void watchOut() {
    System.out.println("Be careful!");
  }
}

switch 语句的另外一个常见用法是在不同的分支中对同一个变量进行赋值。如下面的代码所示。这种写法比较繁琐。

public class SwitchStatementAssignment {

  enum TrafficColor {
    RED, YELLOW, GREEN
  }

  public String getMessage(TrafficColor color) {
    String message;
    switch (color) {
      case RED:
        message = "Stop!";
        break;
      case GREEN:
        message = "Go!";
        break;
      default:
        message = "Be careful!";
    }
    return message;
  }
}

为了解决这两个问题,可以用到 switch 表达式和箭头标签。

switch 表达式在 Java 12 中以预览功能的形式引入,在 Java 13 中再次预览,在 Java 14 中成为正式功能。

switch 可以作为表达式来使用,因此可以有自己的值。这就简化了赋值操作。switch 表达式的值由分支来确定。下面的代码展示了 switch 表达式的基本用法。

public class SwitchExpression {

  public String formatGifts(int number) {
    return switch (number) {
      case 0 -> "no gifts";
      case 1 -> "only one gift";
      default -> number + " gifts";
    };
  }
}

在上述代码中,switch 表达式使用的不是传统的冒号,而是箭头。在使用了箭头之后,代码执行不会转到下一个分支,相当于添加了 break。在下面的代码中,同样的 trafficControl 方法,使用箭头标签之后,就不再需要使用 break

public class SwitchLabel {

  enum TrafficColor {
    RED, YELLOW, GREEN
  }

  public void trafficControl(TrafficColor color) {
    switch (color) {
      case RED -> System.out.println("Stop!");
      case YELLOW -> System.out.println("Be careful!");
      case GREEN -> System.out.println("Go!");
    }
  }
}

大多数情况下,箭头标签之后使用单个表达式就可以满足需求。如果有复杂的逻辑,可以使用代码块。这个时候就需要用 yield 来提供值。

public class YieldValue {

  public String formatGifts(int number) {
    return switch (number) {
      case 0 -> "no gifts";
      case 1 -> "only one gift";
      default -> {
        if (number < 0) {
          yield "no gifts";
        } else {
          yield number + " gifts";
        }
      }
    };
  }
}

在使用传统标签的 switch 语句中,也是可以使用 yield

public class YieldValue2 {

  public String formatGifts(int number) {
    return switch (number) {
      case 0:
        yield "no gifts";
      case 1:
        yield "only one gift";
      default: {
        if (number < 0) {
          yield "no gifts";
        } else {
          yield number + " gifts";
        }
      }
    };
  }
}

关于 switch 表达式的内容,就介绍到这里。相应的视频见我的B站

版权所有 © 2024 灵动代码