重複是學習之母。雖然我們之前已經討論過 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之間的主要區別在於break從case語句返回執行控制,而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 開髮變得更加酷炫。