Java SE 9 搭載了模組化、REPL、編譯器優化以及很多其他功能,一直以來 Java 的版本命名和釋出週期也將發生重大變化。

Java 9 - 正式的名稱是 Java 平臺標準版版本號 9 - 終於釋出了,Java 開發工具包(JDK) 也已經可供開發者下載。

新版本增加了幾個重要且富有爭議的功能,同時它也是一直以來遵循 Java 版本命名規範和釋出週期的最後一個版本。

下載 Java 9 JDK

Java 9 的關鍵新特性

在 Java SE 8 釋出將近三年後,Java SE 9 終於釋出,它帶來幾個重大的架構變化,以及一系列的改進。

Java 9 的模組化是顛覆性

基於 Jigsaw 專案,這個新的富有爭議性的模組化能力肯定會引來最前沿 Java 開發者的興趣和嘗試,即使會有更保守的開發者決定等待模組化的成熟。

模組化-以 Java 平臺模組系統的形式-將 JDK 分成一組模組,可以在執行時,編譯時或者構建時進行組合。模組化被稱為一個“可傳遞”的更改,它支援對模組間依賴的理解。

Java 9 的模組化能讓開發者更容易的組合和維護複雜的應用程式。同時,它也使 Java 在改進安全和效能的同時能夠更好的適配到更小的裝置中。

Java 9 的模組化包含應用打包,JDK 自身模組化,以及將原始碼重新組織成多個模組。構建系統在構建時編譯模組和識別模組邊界的能力也得到增強。JDK 和 Java 執行時環境(JRE)的映象經過重構以處理模組化。另外,JavaFX UI 控制元件和 CSS APIs 現在也支援模組化方式訪問。

Java 9 支援很多配置,因此,可伸縮性,安全性和應用程式效能應該得到改善。讓 Java 更容易適配到小型裝置中是模組化的關鍵推動力。

通過模組化,開發者將能夠更好的使用 Java SE(標準版本) 和 Java EE(企業版本) 構建和維護函式庫和大型應用。但在 Java 9 開發期間,Oracle,IBM,Red Hat 和其他公司關於如何在 Java 平臺實施這樣的重大改動有很大的分歧。模組化系統本身在五月份被否決,取得一定進展後,在六月份第二次投票中才獲得批准。

即使主要的 Java 供應商之間已經取得了一致,但關於模組化能給 Java 開發者帶來多大好處,專家們褒貶不一。無論如何,Java 9 現在已經支援模組化了。

為了更容易的將程式碼遷移到模組化的 Java 9,Java 9 允許開發者對類路徑中的程式碼進行非法的反射訪問,這一能力被 JRE 用來搜尋類和資原始檔,當然,這個能力在 Java 9 之後將會禁用。

改進的 Java 9 程式碼編譯

Java 9 的升級帶來了幾個程式碼編譯的新功能,其中最主要的是 AoT(ahead-of-time)編譯。雖然仍處於試驗階段,但這個功能使得 Java 應用在被虛擬機器啟動之前能夠先將 Java 類編譯為原生程式碼。此功能旨在改進小型和大型應用程式的啟動時間,同時對峰值效能的影響很小。

JIT(Just-in-time)編譯器速度很快,但是 Java 專案現在變得很大很複雜,因此 JIT 編譯器需要花費較長時間才能熱身完,而且有些 Java 方法還沒法編譯,效能方面也會下降。AoT 編譯就是為了解決這些問題而生的。

但是 Java 技術供應商 Excelsior 的營銷總監 Dmitry Leskov 擔心 AoT 編譯技術不夠成熟,希望 Oracle 能夠等到 Java 10 時有個更穩定版本才釋出。

Java 9 同時還提供了 Oracle 智慧編譯部署的階段二功能。這個功能包括改進了 s javac 工具的穩定性和可移植性,從而能夠被 JVM 預設使用。這個工具也將會做得更通用,從而可以使用在除 JDK 之外的其他大型專案中。JDK 9 還更新了 javac 編譯器以便能夠將 java 9 程式碼編譯執行在低版本 Java 中。

另一個新的同時也是試驗性的功能是 JVMCI(Java-level JVM Compiler Interface)。通過這個介面,用 Java 編寫的編譯器可以被 JVM 當作動態編譯器使用。JVMCI 的 API 提供訪問虛擬機器結構,安裝編譯過的程式碼,以及插入 JVM 編譯系統中的機制。

使用 Java 編寫的 JVM 編譯器相比已有的用 C 或者 C++ 編寫的編譯器,能夠在保持高質量的同時更容易維護和改進。因此,使用 Java 編寫的編譯器本身應該更容易維護和改進。其他使用 Java 編寫編譯器的嘗試包含 Graal 專案和 Metropolis 專案

新的編譯器控制能力旨在為 JVM 編譯器提供細粒度和方法上下文相關的控制,讓開發者在執行時不降低效能的前提下修改編譯器控制選項。這個工具還支援為 JVM 編譯器存在的 bug 提供解決方法。

Java 9 終於有了 REPL

Java 9 的另一個特性是擁有了 REPL(read-eval-print loop)工具,這是另一個 Java 的長期目標,在 Kulia 專案中經過多年研發後終於在 Java 9 中得以實現。

Java 9 的 REPL 名為 jShell,以互動式的方式對語句和表示式進行求值。開發者只需要輸入一些程式碼,就可以在編譯前獲得對程式的反饋。

命令列工具的功能包含 tab 自動補全和自動新增分號。jShell API 支援在 IDE 和其他工具中使用 jShell 功能,雖然這個工具本身不是 IDE。

REPL 的缺失是高校想要把 Java 從學校課程中剔除的一個原因(像 Python 和 Scala 之類的語言早就有 REPL 了)。但 Scala 語言的創始人 Martin Odersky 質疑 Java 中 REPL 的作用,他說 Java 是面向語句的,而 REPL 是面向表示式的。

Java 9 增強了 Steam API

Java 的 Steam 讓開發者能夠快速運算,從而能夠有效的利用資料平行計算。Java 8 提供的 Steam 能力能夠利用多核架構實現宣告式的資料處理。

在 Java 9 中,Stream API 通過新增方法, 實現有限制的從 Stream 中新增或者移除元素,遍歷 Stream 中的元素,以及通過擴充套件 Java SE API 集合實現從空值建立流的功能。

Java 9 支援程式碼快取的分割

JDK 9 支援將程式碼快取分割成段,從而提高效能並實現擴充套件功能,例如細粒度鎖。由於使用專門的迭代器忽略非方法程式碼,分離非方法,剖析和非剖析程式碼,結果掃描時間將得到改進。某些基準的執行時間也得到改進。

通過 Nashorn 專案 Java 9 更好的支援 Javascript

Nashorn 專案在 JDK 9 中得到改進,它為 Java 提供輕量級的 Javascript 執行時。Nashorn 專案跟隨 Netscape 的 Rhino 專案,目的是為了在 Java 中實現一個高效能但輕量級的 Javascript 執行時。Nashorn 專案使得 Java 應用能夠嵌入 Javascript。它在 JDK 8 中為 Java 提供一個 Javascript 引擎。

JDK 9 包含一個用來解析 Nashorn 的 ECMAScript 語法樹的 API。這個 API 使得 IDE 和服務端框架不需要依賴 Nashorn 專案的內部實現類,就能夠分析 ECMAScript 程式碼。

Java 9 引入 HTTP/2 客戶端 API

Java 9 引入了 beta 版的 HTTP/2 客戶端 API,升級了 Web 核心 HTTP 協議,這個 API 同時也支援 WebSocket。

HTTP/2 API 可以用來代替 HttpURLConnection API,後者存在一些缺點,包括當初是為現在已經失效的協議所設計,早於 HTTP/1,介面定義太抽象以及使用起來不容易。

Java 9 改進了對 HTML5 和 Unicode 的支援

在 JDK 9 中,Javadoc 文件工具經過增強現在支援生成 HTML5 標記文件。Unicode 8.0 編碼標準也得到支援,該標準新增 8000 個字元,10 個塊和 6 個指令碼。

Java 9 新增 DTLS 安全 API

為了安全,Java 9 新增支援 DTLS(Datagram Transport Layer Security) 的 API。這個協議用來在客戶端伺服器通訊中防止竊聽,篡改,訊息偽造等。客戶端和服務端模式都提供了實現。

Java 9 廢棄和移除的 API

Java 9 廢棄或者移除了幾個不常用的功能。其中最主要的是 Applet API,現在是標記為廢棄的。隨著對安全要求的提高,主流瀏覽器已經取消對 Java 瀏覽器外掛的支援。HTML5 的出現也進一步加速了它的消亡。開發者現在可以使用像 Java Web Start 這樣的技術來代替 Applet,它可以實現從瀏覽器啟動應用程式或者安裝應用程式。

同時,appletviewer 工具也被標記為廢棄。

Java 9 還廢棄了並行標記掃描(CMS,Concurrent Mark Sweep)垃圾回收器,在未來的釋出版本中將進一步停止支援。其目的是加速 HotSpot 虛擬機器中其他垃圾回收器的發展。低暫停 G1(low-pause G1) 回收器將是 CMS 的長期替代品。

同時,之前在 JDK 8 中廢棄的垃圾收集組合在 JDK 9 中已經刪除。這包括很少使用的組合,例如增量 CMS,ParNew + SerialOld,DefNew + CMS,這些給垃圾收集器的程式碼庫增加了額外的複雜性。

Java 9 也忽略了 Java 匯入語句的警告,以有助於大型程式碼庫維持更乾淨的 lint 警告。在這些程式碼庫中,廢棄的功能通常還需要繼續使用一段時間,程式碼中匯入廢棄類或者方法,如果是開發者有意為之,並且通過註解抑制這些警告資訊,那麼警告資訊將不會顯示出來。

在 Java 9 中同時移除的還有通過 Multiple JRE(mJRE)功能在啟動時選擇 JRE 版本 的功能。這個功能很少使用,同時使 Java 啟動器的實現複雜化,自從在 JDK 5 開始出現以來,一直沒有完整的文件描述。

Oracle 已經移除 JVM TI(Tool Interface)hprof(Heap Profiling) 代理,它在 JVM 中已經被代替。jhat 工具也被移除,它早已被更好用的堆疊視覺化和分析工具所代替。

Java 9 是當前時間線的終結者,新的時間線從此展開

Java 9 的帶來了很多新功能。Oracle 最近透漏 Java 9 將是最後一個遵循 Java 名稱命名規範和主版本釋出週期的版本。

從現在開始,Java 的計劃釋出週期是 6 個月,下一個 Java 的主版本將於 2018 年 3 月釋出,命名為 Java 18.3,緊接著再過六個月將釋出 Java 18.9。

Java 新的釋出週期也意味著 JDK 9 將不會被作為長期支援版本。相反,下一個長期支援釋出版本是 Java 18.9。

Java 更快的釋出週期意味著開發者將不需要像以前一樣為主要釋出版本望眼欲穿。這也意味著開發者將可能跳過 Java 9 和它的不成熟的模組化功能,只需要再等待 6 個月就可以迎來新版本,這將有可能解決開發者的糾結,Simon Maple 這樣說,他是 Java 工具供應商 ZeroTurnaround 的 Java 支持者。