16個主要增強功能,2400個錯誤修復等
> Photo by Fab Lentz on Unsplash
Java 14將於2020年3月17日釋出。除了約2,400個錯誤修復和小的增強功能之外,Java的新版本還包含16個主要增強功能,也稱為JEP(Java增強建議)。
讓我們仔細看一下Java 14中的主要更新:新的開關表示式,更好的NullPointerExceptions,垃圾收集方面的改進,JFR事件流等等。
> Image source: Author
Case表示式Java語言的此更新已在Java 12和13中提供,但僅作為預覽語言功能提供,這意味著預設情況下未啟用。 最後,新的switch表示式在Java 14中釋出。總而言之,Java 14引入了一種新的簡化形式的switch塊,帶有case L-> …標籤。 在某些情況下,新的開關表示式可能有助於簡化程式碼。 這裡有幾個例子。
假設我們有一個描述工作日的列舉。 我們可以使用新的switch表示式編寫以下程式碼:
switch (day) { case MONDAY -> System.out.println("Aweful"); case TUESDAY, WEDNESDAY -> System.out.println("Okay"); case THURSDAY -> System.out.println("Good"); case FRIDAY -> System.out.println("Great"); case SATURDAY, SUNDAY -> System.out.println("Awesome");}在這裡,我們只為每種情況使用一個表示式。 請注意,switch塊不使用任何break語句,這使其更短。 下一個示例顯示新的開關表示式如何返回值:
int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9;};也可以編寫多行程式碼塊並返回帶有新關鍵字yield的值:
int result = switch (s) { case "Foo" -> 1; case "Bar" -> 2; default -> { System.out.println("Neither Foo nor Bar, hmmm..."); \tyield 0; \t}};使用新的開關表示式時,需要牢記一些重要的事情。 例如,新開關表示式的情況必須詳盡無遺。 這意味著,對於所有可能的值,必須有一個匹配的開關標籤。 或者,由於yield現在是關鍵字,因此具有名稱yield的類現在在Java 14中變得非法。
有用的NullPointerExceptions當代碼嘗試取消引用空引用時,JVM丟擲NullPointerException(NPE)。 所有Java開發人員以前都看過它們。 例如,以下程式碼可能會導致NPE:
foo.bar = 10;
NPE將如下所示:
Exception in thread "main" java.lang.NullPointerException at App.main(App.java:17)
異常訊息包含檔名和發生空解除引用的行。 對於foo.bar = 10; 宣告,因為foo變數為null,所以丟擲NPE並不難。 不幸的是,有時不清楚是什麼原因導致了NPE。 例如,如果a,b或c為空,則將引發NPE:
a.b.c.d = 42;
但是,無論哪個欄位為空,NPE都將看起來相同。 它沒有任何線索表明哪個欄位實際上為空。
這是另一個例子。 如果巢狀陣列之一為null,則將導致NPE:
a[i][j][k] = 99;
同樣,無論哪個陣列為空,NPE都將看起來相同。
Java 14解決了這個問題,並使NPE更友好。 現在,JVM可以找出哪個變數為null,然後在異常訊息中讓使用者知道它。 例如,在foo.bar = 10行中的空取消引用; 將導致以下NPE:
Exception in thread "main" java.lang.NullPointerException: Cannot assign field "bar" because "foo" is null at App.main(App.java:17)
行a.b.c.d = 41中的空取消引用; 如果a.b為空,將導致以下NPE:
Exception in thread "main" java.lang.NullPointerException: Cannot read field "c" because "a.b" is null at App.main(App.java:17)
NullPointerExceptions中的新資訊可能對分析其根本原因很有幫助,並且可以使開發人員的生活更加輕鬆。 順便說一句,自2006年以來,SAP的JVM中就已進行了改進。不幸的是,最終將其引入OpenJDK花費了14年的時間。
如果您對這些細節感興趣,JEP 358的作者提供了有關此新功能的大量資訊。
包工具(培養箱)當前,Java應用程式通常以簡單的JAR檔案的形式分發。 但是,這並不是很方便,特別是對於應用程式的使用者而言。 如果Java應用程式是可安裝的軟體包,例如Windows上的MSI或Mac上的DMG,那就更好了。 這將允許Java應用程式以使用者熟悉的方式進行分發,安裝和解除安裝。
JEP 343引入了jpackage工具,該工具將Java應用程式打包到包含所有必要依賴項的特定於平臺的程式包中。 以下是受支援的軟體包格式的列表:
· Linux上的DEB和RPM
· Mac OS上的PKG和DMG
· Windows上的MSI和EXE
這是如何使用新工具的示例:
$ jpackage --name myapp --input lib --main-jar main.jar \\
--main-class myapp.Main
它獲取lib / main.jar檔案,並以最適合其執行系統的格式生成一個軟體包。 入口點是myapp.Main類。
JEP的作者提供了許多有關新工具的有用資訊。
儘管JDK 14中提供了jpackage工具,但它是作為孵化器模組提供的,這意味著該功能不能保證穩定,並且可能在將來的版本中進行修改。
更好的垃圾收集Java 14在垃圾回收方面包含多項增強功能。
JEP 345通過實現可識別NUMA的記憶體分配來改進G1垃圾收集器。 順便說一下,NUMA代表非統一記憶體訪問。 此功能已在並行垃圾收集器中實現很長時間了。 現在,可以通過使用新的+ XX:+ UseNUMA命令列選項執行Java來在G1中啟用它。 這將改善大型計算機上的G1效能。
JEP 364和JEP 365使Z垃圾收集器(ZGC)在macOS和Windows上可用。 ZGC是併發垃圾收集器,幾年前新增到JVM中。 ZGC試圖減少垃圾收集的暫停時間,並且可以處理大小從幾百兆位元組到幾兆位元組不等的堆。 以前,收集器只能在Linux上執行。 JEP 366不贊成使用Parallel Scavenge和Serial Old垃圾收集演算法的組合。 使用者必須使用-XX:+ UseParallelGC -XX:-UseParallelOldGC命令列選項啟用此組合。 作者認為,這種組合並不常見,但需要大量的維護工作。 實際上,選項-XX:UseParallelOldGC現在已被棄用。 如果使用了過時的模式,將顯示一個warring。
JFR事件流JDK Flight Recorder(JFR)是JVM中內建的事件記錄器。 它捕獲有關JVM本身以及JVM中執行的應用程式的診斷和概要分析資料。 JFR曾經是專有工具,但它在2018年開源,作為OpenJDK 11的一部分發布的Java。
要使用JFR提供的資料,使用者必須開始錄製,停止錄製,將內容轉儲到磁碟,然後解析錄製檔案。 這對於應用程式概要分析非常有效,但不適用於監視目的。
在Java 14中,JFR允許使用者非同步訂閱事件。 使用者現在可以註冊一個處理程式,以響應事件的到來而呼叫該處理程式。 RecordingStream類提供了一種統一的方法來過濾和使用事件。 這是JEP作者提供的示例:
可以在JEP 349中找到更多資訊。
語言預覽功能Java 14包含對Java語言的若干更新,預設情況下尚不可用。
首先,JEP 305使用繫結變數擴充套件instanceof運算子。 這是一個例子:
if (obj instanceof String s) {
// can use s here
}
如果obj是String的例項,則將其強制轉換為String並分配給繫結變數s。
其次,JEP 359將記錄引入Java語言。 記錄具有名稱和狀態描述。 狀態描述宣告記錄的組成部分。 唱片也可能有身體。 這是一個簡短的示例:
record Point(int x, int y) {}
第三,在收集了針對Java 13的反饋之後,JEP 368為先前在Java 13中作為語言預覽功能引入的文字塊添加了兩個新的轉義序列。
不幸的是,這三個更新仍僅作為預覽語言功能提供,預設情況下未啟用。 要啟用新語法,您必須使用–enable-preview –release 14選項執行Java編譯器,然後使用–enable-preview選項啟動Java:
$ javac -d classes --enable-preview --release 14 Test.java
$ java -classpath classes --enable-preview Test
其餘的部分Java 14還有哪些其他變化?
JEP 370引入了一個API,以允許Java應用程式安全有效地訪問Java堆外部的外部記憶體。 聽起來嚇人。 新的API應該成為java.nio.ByteBuffer和sun.misc.Unsafe類的替代方法。 此功能作為孵化模組提供。
JEP 352添加了新的檔案對映模式,以便可以使用FileChannel API建立引用非易失性儲存器(NVM)的MappedByteBuffer例項。
如果您了解Solaris和SPARC,JEP 362將放棄對Solaris / SPARC,Solaris / x64和Linux / SPARC平臺的支援。 將來,這些平臺上的埠很可能將從OpenJDK中刪除。
結論與Java 13中的五個JEP相比,新的Java 14提供了更多的主要增強功能。 更新涉及各個領域。 對於Java開發人員而言,最可能最有趣的更新將是新的開關表示式和增強的NullPointerExceptions。 不要忘記嘗試新的語言預覽功能,並將您的反饋提供給JDK開發人員。 享受新的Java 14!
連結· OpenJDK 14時間表和增強功能列表
(本文翻譯自Artem Smotrakov的文章《What's New in Java 14?》,參考:https://medium.com/better-programming/whats-new-in-java-14-a472ec291c05)