重复是学习之母。虽然我们之前已经讨论过 Java 的switch关键字,但今天我们将回顾基础知识并挖掘一些新信息。

Java 有两种类型的switch结构:switch 语句和 switch 表达式。switch 表达式在 Java 14 中正式出现,在版本 12 和 13 中以两个非官方的“预览”变体存在。

但让我们从头开始。让我们回忆一下在版本 12 之前一个好的旧开关是什么样子的:


public String getProductTypeByName(String product) {
    String productType = "";

    switch (product) {
        case "Apple":
            productType = "Fruit";
            break;

        case "Peach":
            productType = "Fruit";
            break;

        case "Raspberry":
            productType = "Berry";
            break;

        case "Cherry":
            productType = "Berry";
            break;

        case "Tomato":
            productType = "Vegetable";
            break;

        default:
            productType = "other";
            break;
    }
        
    return productType;
}

switch 语句是一组将一个接一个地执行的结构。它不允许您返回值。使用 switch 语句的主要问题是您可以添加无数个case表达式,而这种能力经常被程序员滥用。

Java 12 增加了一项实验性功能:新版本的 switch——不是 switch 语句,而是 switch 表达式——它可以产生一个值,在内部使用函数式编程,并合并具有共同值的 case 语句,从而使构造紧凑。

在 Java 12 中,您可以重写getProductTypeByName()方法,如下所示:


public String getProductTypeByName(String product) {
    return switch (product) {
        case "Apple", "Peach" -> "Fruit";
        case "Raspberry", "Cherry" -> "Berry";
        case "Tomato" -> "Vegetable";
        default -> "other";

    };
}

现在代码看起来更干净了。函数式编程的箭头语法让我们可以在不使用break关键字的情况下返回值,通常,执行switch的结果现在可以保存到变量或通过return关键字返回。

如果我们不仅需要返回一个结果,还需要多行代码,那么我们的switch应该是这样的:


public String getProductTypeByName(String product) {
    var result = switch (product) {
        case "Apple", "Peach" -> {
            System.out.println("This is a Fruit");
            break "Fruit";
        }
        case "Raspberry", "Cherry" -> {
            System.out.println("This is a Berry");
            break "Berry";
        }
        case "Tomato" -> {
            System.out.println("This is a Vegetable");
            break "Vegetable";
        }
        default -> {
            break "other";
        }

    };
     return result;
}

在 Java 13 中,switch 表达式仍然是一个实验性特性。要使其可用,就像在 Java 12 中一样,需要在编译和运行时使用--enable-preview命令。Java 13 中switch的主要且基本上唯一的“创新”是yield关键字,它取代了break


public String getProductTypeByName(String product) {
    var result = switch (product) {
        case "Apple", "Peach" -> {
            System.out.println("This is a Fruit");
            yield "Fruit";
        }
        case "Raspberry", "Cherry" -> {
            System.out.println("This is a Berry");
            yield "Berry";
        }
        case "Tomato" -> {
            System.out.println("This is a Vegetable");
            yield "Vegetables";
        }
        default -> {
            System.out.println("Other");
            yield "other";
        }

    };
    return result;
}

yieldbreak之间的主要区别在于breakcase语句返回执行控制,而yield返回整个switch的结果,就像内部return语句一样。

在 Java 14 中,instanceof运算符发生了变化,现在可以像这样使用:


if (o instanceof String s) {
s.toLowerCase();
}

而不是有点丑陋的旧方法,您不仅要使用instanceof检查变量,还要将其转换为特定类型。


if(s instanceof String) {
((String) s).toLowerCase();
}

这些更改是 Amber 项目的一部分,旨在为 Java 添加模式匹配支持。

由于版本 14 中instanceof运算符的更改和版本 16 中的扩展,模式匹配最终确实进入了版本 17。没错,它目前仅作为预览存在。您可以尝试使用--enable-preview


public String getObjectType(Object object) {
    return switch (object) {
        case Integer i -> "Integer";
        case Long l -> "Long";
        case String s -> "String";
        default -> object.toString();
    };
}

总的来说,每个新版本都会为该语言带来越来越多有趣的特性,这让 Java 开发变得更加酷炫。