JDK14新特性之instanceof模式匹配
1. 背景及動機
通過對instanceof運算符進行模式匹配來增強Java編程語言。模式匹配允許程序中的通用邏輯,即從對象中有條件地提取組件,可以更簡潔,更安全地表示。這是JDK 14中的預覽語言功能。
動機
幾乎每個程序都包含某種邏輯,這些邏輯結合了對表達式是否具有某種類型或結構的測試,然後有條件地提取其狀態的組件以進行進一步處理。例如,所有Java程序員都熟悉實例化。經常見到如下代碼:
if (obj instanceof String) {
String s = (String) obj;
// use s
}
這裏發生了三件事:
- 一個測試(obj是一個String嗎?)
- 一個轉換(將obj轉換爲String)以及
- 一個新的局部變量的聲明,以便我們可以使用字符串值。
這種模式很簡單,並且所有Java程序員都可以理解,但是由於一些原因,它不是最優的。這很乏味;不需要進行類型測試和類型轉換(在一個testof實例之後還要做什麼?)。這個樣板-尤其是String類型的三個出現-混淆了後面的更重要的邏輯。但最重要的是,重複爲錯誤提供了機會,使錯誤不被察覺到程序中。
我們認爲Java是時候增強模式匹配了,而不是尋求即席解決方案。模式匹配允許簡潔地表達對象的所需形狀
(模式),並允許各種語句和表達式針對其輸入來測試形狀
(匹配)。從Haskell到C#,許多語言都出於其簡潔性和安全性而接受了模式匹配。
2. 示例
public class InstanceofDemo
{
public static void main(String[] args) {
Object obj = "hello java";
// Object obj = 2345;
instanceTest(obj);
}
public static void instanceTest(Object obj)
{
if (obj instanceof String s)
{
System.out.println(String.format("字符串:%s", s));
}
else if (obj instanceof Integer i)
{
System.out.println(String.format("整數:%s", i));
}
else {
throw new RuntimeException("obj的類型無法處理。");
}
}
}
新的運行邏輯:
新在instanceof
的類型之後添加了變量s
。
如果instanceof
對obj
的類型檢查通過: obj
是String
類型時,會被轉換成String
類型的變量s
。obj
是Integer
類型時,會被轉換成Integer
類型的變量i
。如果判斷不成立的話,無法在下面的花括號中使用其對應聲明的局部變量。
3. 其他
由於instanceof
的模式匹配是預覽功能,需要通過選項--enable-preview --source 14
來啓用。
java --enable-preview --source 14 com/test/InstanceofDemo.java
如果使用的IDEA 2020年以後的版本,配置如下即可使用。