天天看點

JAVA9新特性(二)JAVA9新特性(二)

JAVA9新特性(二)

JLink

JLink是用來組裝和優化子產品以及子產品依賴項成為一組自定義運作鏡像的工具。可以建立針對應用程式進行優化的最小運作時映像而不需要使用完全加載 JDK 安裝版本。

JAVA9新特性(二)JAVA9新特性(二)
JAVA9新特性(二)JAVA9新特性(二)

Java版本更新字元串格式

版本字元串的格式

$MAJOR.$MINOR.$SECURITY.$PATCH。以後将半年發一版,未完成的任務将不再等候,直接等到下一版本釋出。

JAVA9新特性(二)JAVA9新特性(二)

JShell :THE Java Shell(Read-Eval-Print Lopp)

JAVA9新特性(二)JAVA9新特性(二)

Java開發者可以利用JShell(jdk中bin目錄下)在沒有建立類的情況下直接聲明變量,計算表達式,執行語句。JShell也可以從檔案中加載語句或者将語句儲存到檔案中。并且JShell也可以是tab鍵進行自動補全的特性。

代碼分段緩存

Java 9的另一個性能提升來自于JIT(Just-in-time)編譯器. 當某段代碼被大量重複執行的時候, 虛拟機會把這段代碼編譯成機器碼(native code)并儲存在代碼緩存裡面, 進而通過通路緩存中不同分段的代碼來提升編譯器的效率.

和原來的單一緩存區域不同的是, 新的代碼緩存根據代碼自身的生命周期而分為三種:

- 永駐代碼(JVM 内置 / 非方法代碼)

- 短期代碼(僅在某些條件下适用的配置性(profiled)代碼)

- 長期代碼(非配置性代碼)

緩存分段會在各個方面提升程式的性能, 比如做垃圾回收掃描的時候可以直接跳過非方法代碼(永駐代碼), 進而提升效率.

集合工廠方法

Java 9引入了一些有用的工廠方法來建立不可修改的集合。我們現在在Java 9中建立不可修改的Map集合,如下所示。

JAVA9新特性(二)JAVA9新特性(二)
JAVA9新特性(二)JAVA9新特性(二)

接口中私有方法

預設方法和靜态方法可以共享接口中的私有方法,是以避免了代碼備援,這也使代碼更加清晰。

JAVA9新特性(二)JAVA9新特性(二)

改進的JAVADOC

Javadoc 現在支援在 API 文檔中的進行搜尋。另外,Javadoc 的輸出現在符合相容 HTML5 标準。并且每個 Javadoc 頁面都包含有關 JDK 子產品類或接口來源的資訊。

JAVA9新特性(二)JAVA9新特性(二)

改進的Stream API

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

長期以來,Stream API 都是 Java 标準庫最好的改進之一。通過這套 API 可以在集合上建立用于轉換的申明管道。在 Java 9 中它會變得更好。Stream 接口中添加了 4 個新的方法:dropWhile, takeWhile, ofNullable。還有個 iterate 方法的新重載方法,可以讓你提供一個 Predicate (判斷條件)來指定什麼時候結束疊代

除了對 Stream 本身的擴充,Optional 和 Stream 之間的結合也得到了改進。現在可以通過 Optional 的新方法

stram

将一個 Optional 對象轉換為一個(可能是空的) Stream 對象:在組合複雜的 Stream 管道時,将 Optional 轉換為 Stream 非常有用。

HTTP 2

Java 9采用了全新的HTTP用戶端API,這些API支援HTTP/2協定和WebSocket協定,并且替換了遺留的HTTPURLConnectionAPI。這些改變并不應該在Java 9中完成。這些API可以從Incubator(孵化器)子產品中擷取。是以在預設情況下,這個子產品是不能根據classpath擷取的,需要使用–add-modules指令選項配置這個子產品,将這個子產品添加到classpath中。

建立一個HTTPRequest請求和擷取異步的響應:

JAVA9新特性(二)JAVA9新特性(二)

多版本相容JAR

Java 9提供了一種為新API和新的Java語言結構執行此操作的方法: 多版本JAR檔案 。多版本JAR檔案看起來就像之前的JAR檔案一樣,但多了一個關鍵的補充:在JAR檔案中可以放置使用最新Java 9功能的類。如果運作Java 9,則JVM會識别這個類并忽略同一個包中其他同名的類。

JAVA9新特性(二)JAVA9新特性(二)

在上述場景中, multirelease.jar 可以在 Java 9 中使用, 不過 Helper 這個類使用的不是頂層的 multirelease.Helper 這個 class, 而是處在“META-INF/versions/9”下面的這個。這是特别為 Java 9 準備的 class 版本,可以運用 Java 9 所提供的特性和庫。同時,在早期的 Java 諸版本中使用這個 JAR 也是能運作的,因為較老版本的 Java 隻會看到頂層的這個 Helper 類。

廢棄和遺棄的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 的更新帶來了幾個代碼編譯的新功能,其中最主要的是 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 提供解決方法。

緊湊字元串(底層的實作)

采用一個更節省空間的内部表示為字元串。 在此之前,字元串類存儲字元需要使用兩個位元組存儲每個字元(16位)。新的内部表示字元串類是一個位元組數組+一個encoding-flag字段。

Try-with-Resource

在Java 7中,try-with-resouces文法要求為每一個資源聲明一個新的變量,而且這些資源由try-with-resources語句進行管理。

在就Java 9中,有另外一個改進:如果一個資源被final或者等效于final變量引用,則在不需要聲明一個新的變量的情況下,try-with-resources就可以管理這個資源。

JAVA9新特性(二)JAVA9新特性(二)

鑽石(diamond)操作符<>

Java 7中鑽石操作符不允許在匿名類上使用。但在Java 9中改善了這一情況,允許鑽石操作符在匿名類上使用。下面的例子隻有在Java 9中才能通過編譯。

JAVA9新特性(二)JAVA9新特性(二)

單個下劃線不再是合法字元

JAVA9新特性(二)JAVA9新特性(二)

@SafeVarargs

@SafeVarargs注釋可以僅适用于方法不能被覆寫。之前隻能在static或final以及構造方法上,在Java SE 9中,多加入私有執行個體方法。

JAVA9新特性(二)JAVA9新特性(二)

@Deprecated增強

@Deprecated(since= “version”)

version是當API被棄用的版本号,表面該API将被棄用在版本的Java SE平台。預設值為空字元串(“”)。

@Deprecated(forRemoval =)

forRemoval = true表明,該API在将來釋出的版本中移除。

forRemoval = false建議代碼應該不再使用這個API; 然而,目前沒有計劃把API删除。 預設值為false。

@Deprecated(since=”9”, forRemoval=true)

表明此API将于版本9删除

Process API

在Java 9之前,可以啟動本地程序并使用其輸入,輸出和錯誤流。 但是,無法使用未啟動的本地程序,無法查詢程序的詳細資訊。 為了更緊密地處理本地程序,Java開發人員不得不使用Java Native Interface(JNI)來編寫本地代碼。 Java 9使這些非常需要的功能與本地程序配合使用。

Java 9向Process API添加了一個名為ProcessHandle的接口。 ProcessHandle接口的執行個體辨別一個本地程序; 它允許查詢程序狀态并管理程序。