Java 11 正式釋出,新特性解讀!
北京時間 9 月 26 日,Oracle 官方宣佈 Java 11 正式釋出。這是 Java 大版本週期變化後的第一個長期支援版本,非常值得關注。你可以點選以下地址即刻下載:
https://www.oracle.com/technetwork/java/javase/downloads/index.html
最新發布的 Java11 將帶來 ZGC、Http Client 等重要特性,一共包含 17 個 JEP(JDK Enhancement Proposals,JDK 增強提案)。
JDK 11 主要特性
【小編也是一名從事了6年java開發的全棧工程師,花了近一個月整理了一份較適合18年學習的java乾貨,送給每一位學習java小夥伴,加java學習qq群領取:818464711】
最新發布的 JDK 11 共帶來了 17 項更新:
- 181:Nest-Based Access Control(基於巢狀的訪問控制)
- 309:Dynamic Class-File Constants(動態類檔案常量)
- 315: Improve Aarch64 Intrinsics(改進 Aarch64 內部函式)
- 318:Epsilon: A No-Op Garbage Collector(Epsilon:No-Op 垃圾收集器)
- 320:Remove the Java EE and CORBA Modules(刪除 Java EE 和 CORBA 模組)
- 321:HTTP Client (Standard)(HTTP 客戶端)
- 323:Local-Variable Syntax for Lambda Parameters(Lambda 引數的變數語法)
- 324:Key Agreement with Curve25519 and Curve448(採用 Curve25519 和 Curve448 演算法實現的金鑰協議)
- 327:Unicode 10
- 328:Flight Recorder(飛行記錄器)
- 329:ChaCha20 and Poly1305 Cryptographic Algorithms(ChaCha20 和 Poly1305 加密演算法)
- 330:Launch Single-File Source-Code Programs(啟動單檔案原始碼程式)
- 331:Low-Overhead Heap Profiling(低開銷堆分配取樣方法)
- 332: Transport Layer Security (TLS) 1.3(TLS 1.3 的傳輸層安全性)
- 333:ZGC: A Scalable Low-Latency Garbage Collector(Experimental)(ZGC:可擴充套件的低延遲垃圾收集器,在實驗階段)
- 335:Deprecate the Nashorn JavaScript Engine(棄用 Rhino JavaScript 引擎)
- 336:Deprecate the Pack200 Tools and API(棄用 Pack200 工具和 API)
從開發者的角度來看,上面的特性中有幾點需要特別關注。
一
JEP 323 實現了 Java 10 中引入的區域性變數型別推斷的擴充套件。型別推斷是從其餘原始碼和鍵入規則中推匯出的資料型別。這節省了開發者的工作時間,且不會使原始碼過於複雜,而提高了可讀性。
從 Java 10 開始,可以使用關鍵字 var 宣告區域性變數,如下所示:
// Funktioniert seit Java 10 var zahl = 5; // int var string = "Hello World"; // String var objekt = BigDecimal.ONE; // BigDecimal
在 Java 11 中,不同點在於開發者可以使用 var 宣告 lambda 引數。乍一看,這一舉措似乎有點多餘,因為在寫程式碼過程中可以省略 lambda 引數的型別,並通過型別推斷確定它們。但是,副檔名對於使用 @Nonnull 和 @Nullable 等型別註釋很有用。
// Inference von Lambda-Parametern Consumer<String> printer = (var s) -> System.out.println(s); // statt s -> System.out.println(s); // aber keine Mischung von "var" und deklarierten Typen möglich // BiConsumer<String, String> printer = (var s1, String s2) -> System.out.println(s1 + " " + s2); // Nützlich für Type Annotations BiConsumer<String, String> printer = (@Nonnull var s1, @Nullable var s2) -> System.out.println(s1 + (s2 == null ? "" : " " + s2));
二
JDK 11 中另一個亮點在於仍處於實驗階段的新 HTTP Client API 的標準化,該 API 在 JDK 9 中被引入,在 JDK 10 中進行了更新,在本次 JDK 11 中包名由 jdk.incubator.http 改為 java.net.http。HTTP Client API 除了實現了HTTP(1.1和2)、WebSocket,同步和非同步呼叫以及 Reactive Streams 現在也受支援。還使用清晰易懂的 Fluent 介面,將來可能會淘汰其他 HTTP 客戶端(如 Apache)的使用。
HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("http://openjdk.java.net/")) .build(); client.sendAsync(request, asString()) .thenApply(HttpResponse::body) .thenAccept(System.out::println) .join();
三
JEP 330(啟動單檔案原始碼程式)現在可以啟動尚未編譯的類。如今單檔案程式在編寫小實用程式時很常見,特別是指令碼語言領域。從中開發者可以省去用 Java 編譯程式等不必要工作,以及減少新手的入門障礙。在基於 Java 10 的程式中可以通過三種方式啟動:
- 作為* .class檔案
- 作為* .jar檔案中的主類
- 作為模組中的主類
現在,Java 11 中可以在原始碼檔案中宣告類:
# java HelloWorld.java // statt # javac HelloWorld.java # java -cp . hello.World
在 Unix 作業系統上,Java 檔案甚至可以直接作為 Shebang 檔案執行:
#!/path/to/java --source version # ./HelloWorld.java
其他值得注意的變化包括支援 Unicode 10 標準以及將 Profiler Flight Recorder 整合到 OpenJDK 中(之前僅適用於 Oracle JDK)。Flight Recorder 的目標是儘可能高效地記錄應用程式資料,以便在出現問題時分析 Java 應用程式和 JVM。
API 的變化
此外,Java 類庫也有不少小的改動。 特別是字串:
| Welcome to JShell -- Version 11 | For an introduction type: /help intro // Unicode zu String jshell> Character.toString(100) $1 ==> "d" jshell> Character.toString(66) $2 ==> "B" // Zeichen mit Faktor multiplizieren jshell> "-".repeat(20) $3 ==> "--------------------" // Enthält ein Text keine Zeichen (höchstens Leerzeichen)? jshell> String msg = "hello" msg ==> "hello" jshell> msg.isBlank() $5 ==> false jshell> String msg = " " msg ==> " " jshell> msg.isBlank() $7 ==> true // Abschneiden von führenden oder nachgelagerten Leerzeichen jshell> " hello world ".strip() $8 ==> "hello world" jshell> "hello world ".strip() $9 ==> "hello world" jshell> "hello world ".stripTrailing() $10 ==> "hello world" jshell> " hello world ".stripLeading() $11 ==> "hello world " jshell> " ".strip() $12 ==> "" // Texte zeilenweise verarbeiten jshell> String content = "this is a multiline content Mostly obtained from some file which we will break into lines using the new api" content ==> "this is a multiline content Mostly obtained fro ... ines using the new api" jshell> content.lines().forEach(System.out::println) this is a multiline content Mostly obtained from some file which we will break into lines using the new api
Java 11 計劃於本月,即 9 月 25 日釋出。與 Java 10 不同,Java 11 不僅提供了長期支援,還將作為 Java 平臺的參考實現。新的長期支援版本每三年釋出一次,根據後續的釋出計劃,Java 17 將於 2021 年釋出。
Java 11:刪除了什麼?
Oracle JDK 將不再包含 JavaFX(OpenJDK 從未提供過)。相反,JavaFX 通過 OpenJFX 作為單獨的下載提供,並且可以像任何 Java 應用程式中的任何其他庫一樣使用。除 JavaFX 外,還將停止對 Applet 和 Java Web Start 的支援。如果仍然想使用 Java Web Start,那麼必須保持在 JDK 8 的版本,直至 Oracle 停止免費更新後,花錢購買該服務。
另一個在 Java 11 中被棄用的 JavaScript 引擎 Rhino。預計它將在 Java 的未來版本中徹底消失。不過值得注意的是,Rhino 從未真正將自己斷言為 Node.js 上的伺服器端 JavaScript 實現基礎。通過 GraalVM,Oracle 現在採用其他方式在 JVM 上本地執行其他程式語言。
順便說一下,從 Java 11 開始,Java 執行時環境(JRE)將僅存在於伺服器版本中,而不再存在於桌面中。但是,對於具有模組系統和 jlink 工具的桌面應用程式,開發者現在可以輕鬆建立或調整執行時環境。
JDK 11 是否值得更新?
今年四月,Oracle 釋出官方宣告表示即將停止對 JDK 8 的正常支援(免費更新):
2019 年 1 月之後,Oracle 將不會在其網站上釋出 Java SE 8 商業使用的進一步更新下載。如需持續獲取安全的 Bug 修復和安全補丁以及 Java SE 8 或以前版本的穩定性支援,可以通過 Oracle Java SE 高階版、Oracle Java SE 高階桌面、或 Oracle Java SE 套件。
這意味著,在 2019 年 1 月之後,開發者想要使用老版本只能付費了,從中也側面看出,Oracle 在間接性鼓勵使用者主動升級。不過,據各種對 Java 使用者調查如 Jaxenter 發現,大多數的開發者依舊停留在 Java 8 以內的版本。
其實,這也不足為怪,當開發者剛開始吐槽新版本帶來的問題時,Java 已搭載上了火箭更新到了下一版本,讓大家措手不及。此前,就連 Java Collection Framework 的建立者 Josh Bloch 都在吐槽 Java 9 模組系統(Project Jigsaw)帶來令人頭痛的問題,甚至建議:
現在說 Project Jigsaw 將在 JDK 之外實現廣泛使用還為時過早。與此同時,除非你有迫切需要,否則最好避免使用它們。
那麼對於 JDK 11 是否值得立即更新使用?按照 Oracle 公佈支援的路線圖來看,如文章開頭所述,Java 11 將會獲得 Oracle 長期的服務支援,直至 2026 年 9 月。相比 Java 9 和 10 這兩個僅提供半年技術支援的版本來說,JDK 11 的釋出無疑對個人開發者以及企業都是一件好事。
那麼,再結合其新特性,你會選擇更新到 JDK 11 嗎?