Java 14 計劃於 3 月 17 號發佈。這一版本包含的 JEP 比 Java 12 和 Java 13 的總和還要多。那麼,對於每天需要面對 Java 代碼的開發者來說,哪些東西最值得關注?
本文將着重介紹以下這些 Java 新特性:
-
改進的 switch 表達式。這一特性已經作爲預覽版出現在 Java 12 和 Java 13 中,而 Java 14 將帶來它的完整正式版。
-
instanceof 的模式匹配(這是個一語言特性)。
-
非常有用的 NullPointerException 信息(這是一個 JVM 特性)。
switch 表達式
在 Java 14 中,switch 表達式是一個正式的特性。而在之前的兩個 Java 版本中,這個特性只是預覽版。設定“預覽版”的目的是爲了收集開發者反饋,並根據反饋結果決定相應的特性是否要做出修改,甚至是移除,但其中的大部分都會成爲正式特性。
新的 switch 表達式有助於減少 bug,因爲它的表達和組合方式更容易編寫。例如,下面的示例使用了箭頭語法:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
文本塊
Java 13 引入了文本塊特性,並將其作爲預覽版。有了這個特性,處理多行字符串字面量就容易了很多。在 Java 14 中,該特性仍然是預覽版,不過做了一些調整。在沒有這個特性之前,要表示多行格式化的字符串需要像下面這樣:
|
|
|
|
|
|
|
|
|
有了文本塊特性之後,可以使用三引號來表示字符串的開頭和結尾,這樣的代碼看起來更簡潔、更優雅:
|
|
|
|
|
|
|
|
|
|
|
在 Java 14 中,該特性增加了兩個轉義字符。一個是\s,用來表示單空格。一個是反斜槓\,用在行末表示不換行。如果你有一個很長的字符串,爲了讓代碼看起來更好看,但又不希望真的換行,就可以使用這個轉義字符。
例如,目前的多行字符串是這樣的:
|
|
|
|
|
|
|
使用了新的轉義字符之後是這樣的:
|
|
|
|
|
|
|
|
|
instanceof 的模式匹配
爲了避免在使用 instanceof 後還需要進行類型轉換,Java 14 引入了一個新的預覽版特性。例如,在沒有該特性之前:
|
|
|
|
|
|
|
|
|
我們可以使用新的特性來重寫這段代碼:
|
|
|
|
|
既然條件檢查已經確認 obj 是 Group 類型,那爲什麼還要再次進行顯式的類型轉換呢?這樣有可能更容易出錯。新的語法可以將代碼中的大部分類型轉換移除掉。2011 年發佈的一份研究報告顯示,Java 代碼中有 24% 的類型轉換是跟在 instanceof 之後的。
Joshua Bloch 的經典著作《Effective Java》中有一段代碼示例:
|
|
|
|
|
|
|
這段代碼可以使用新的語法寫成:
|
|
|
|
|
|
|
這個特性很有意思,因爲它爲更爲通用的模式匹配打開了大門。模式匹配通過更爲簡便的語法基於一定的條件來抽取對象的組件,而 instanceof 剛好是這種情況,它先檢查對象類型,然後再調用對象的方法或訪問對象的字段。
記錄類(Record)
另一個預覽特性是“記錄”。該特性主要是爲了降低 Java 語法的“囉嗦”程度,讓開發者寫出更簡潔的代碼。這個特性主要用在某些領域類上,這些類主要用於保存數據,不提供領域行爲。
我們以一個簡單的領域類 BankTransaction 作爲例子,它包含了三個字段:date、amount 和 description。目前,這個類需要以下幾個組件:
-
構造器;
-
getter 方法;
-
toString() 方法;
-
hashCode() 和 equals() 方法。
這些方法一般可以通過 IDE 自動生成,但會佔用很大的代碼空間,例如:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Java 14 提供了一種方式,可以避免這種繁瑣的代碼,滿足開發者希望一個類只是用來聚合數據的意圖。BankTransaction 可以重構成:
|
|
|
|
|
除了構造器和 getter 方法,還會自動生成 equals、hashCode 和 toString 方法。
要嘗試這個特性,需要在編譯代碼時打開預覽標籤:
|
記錄類的字段隱式都是 final 的,也就是說不能對它們進行動態賦值。不過要注意,這並不意味着整個記錄類對象都是不可變的,如果字段保存的是對象,那麼這個對象是可變的。
這裏要插一句話,如果從培訓的角度來講,例如你要教會初級開發者,那麼記錄類應該在什麼時候講授比較好?在介紹 OOP 和類的概念之前還是之後?
有用的 NullPointerException 信息
有些人認爲,拋出 NullPointerException 應該成爲 Java 編程的一個新的“Hello world”,因爲這是不可避免的。NullPointerException 確實讓人抓狂,它們經常出現在生產環境的日誌裏,但調試起來很困難。例如,看看下面這段代碼:
|
這段代碼可能會拋出一個異常:
|
|
|
在一行代碼裏連續調用了多個方法,比如 getLocation() 和 getCity(),它們都有可能返回 null,而 user 也可能爲 null。所以,我們無法知道是什麼導致了 NullPointerException。
在 Java 14 中,JVM 會拋出更多有用的診斷信息:
|
|
|
錯誤信息提供了兩個內容:
-
結果:無法調用 Location.getCity()。
-
原因:User.getLocation() 返回值是 null。
要啓用這個功能,需要添加 JVM 標識:
|
例如:
|
據報道,在未來的版本中,這個特性可能會默認啓用。
這個增強特性不僅適用於方法調用,只要會導致 NullPointerException 的地方也都適用,包括字段的訪問、數組的訪問和賦值。
結論
Java 14 帶來了一些新的預覽特性,例如可用於避免顯式類型轉換的 instanceof 模式匹配。它還引入了記錄類,提供了一種簡潔的方式來創建只用於聚合數據的類。另外,增強的 NullPointerException 錯誤信息有助於更好地進行診斷。switch 表達式成爲 Java 14 的正式特性。文本塊進入第二輪預覽,新增了兩個轉義字符