天天看點

JAVA9新特性(一)JAVA9新特性(一)

JAVA9新特性(一)

JAVA9于中原標準時間2017年9月22日(當地9.21)正式釋出,可以在官網上下載下傳到最新的jdk9,但是目前隻支援64位作業系統。

所有特性目錄:http://blog.csdn.net/diehuang3426/article/details/79233952

知乎有個問題描述的也不錯:https://www.zhihu.com/question/65683103/answer/233904009

Java平台級子產品系統(Java Platform Module System)

(PS:此頁全是Java平台級模闆系統,想看其他的,請看JAVA9新特性(二))

什麼是Java Module(子產品)

子產品是代碼和資料集合。 它可以包含Java代碼和本地代碼。 Java代碼被組織為一組包含諸如類,接口,枚舉和注解等類型的類。 資料可以包括諸如圖像檔案和配置檔案的資源。一個子產品不僅僅是一個包的容器。 除了其名稱,子產品定義包含以下内容:

  • 所需的其他子產品(或依賴于)的清單
  • 導出的軟體包清單(其公共API),其他子產品可以使用
  • 開放的軟體包(其整個API,公共和私有)到其他反射通路子產品的清單
  • 使用的服務清單(或使用java.util.ServiceLoader類發現和加載)
  • 提供的服務的實作清單

在使用這些子產品時,可以使用這些方面中的一個或多個。

JAVA9新特性(一)JAVA9新特性(一)

Java SE 9平台規範将平台劃分為稱為平台子產品的一組子產品。 Java SE 9平台的實作可能包含一些或所有平台子產品,進而提供可擴充的Java運作時。 标準子產品的名字是以Java 為字首。Java SE标準子產品的示例有java.base,java.sql,java.xml和java.logging。 支援标準平台子產品中的API,供開發人員使用。

JavaFX不是Java SE 9平台規範的一部分。 但是,在安裝JDK/JRE時,會安裝與JavaFX相關的子產品。 JavaFX子產品名稱以javafx為字首。 JavaFX子產品的示例是javafx.base,javafx.controls,javafx.fxml,javafx.graphics和javafx.web。

作為Java SE 9平台的一部分的java.base子產品是原始子產品。 它不依賴于任何其他子產品。 子產品系統隻知道java.base子產品。 它通過子產品中指定的依賴關系發現所有其他子產品。 java.base子產品導出核心Java SE軟體包,如java.lang,java.io,java.math,java.text,java.time,java.util等。

在JDK 9中,如果一個子產品依賴于另一個子產品,并且運作應用程式時第二個子產品丢失,則在啟動時将會收到一個錯誤,而不是應用程式運作後的某個時間。 這是一個可靠的基礎配置。

子產品的目标

子產品系統的開發具有三大目标:可靠的配置,強封裝,子產品化JDK/JRE。這些目标是解決Java 9之前開發和部署Java應用程式所面臨的問題。

可靠的配置解決了用于查找類型的容易出錯的類路徑機制的問題。 子產品必須聲明對其他子產品的顯式依賴。 子產品系統驗證應用程式開發的所有階段的依賴關系 —— 編譯時,連結時和運作時。 假設一個子產品聲明對另一個子產品的依賴,并且第二個子產品在啟動時丢失。 JVM檢測到依賴關系丢失,并在啟動時失敗。 在Java 9之前,當使用缺少的類型時,這樣的應用程式會生成運作時錯誤(不是在啟動時)。

強大的封裝解決了類路徑上跨JAR的公共類型的可通路性問題。 子產品必須明确聲明其中哪些公共類型可以被其他子產品通路。 除非這些子產品明确地使其公共類型可通路,否則子產品不能通路另一個子產品中的公共類型。 Java 9中的公共類型并不意味着程式的所有部分都可以通路它。 子產品系統增加了更精細的可通路性控制。

子產品化JDK/JRE使得開發和維護更加簡單。例如JRE有一個超級大rt.jar(例如,Java 8的rt.jar中有65M),運作一個hello world,你也需要一個數百兆的JRE環境,如果在J2EE環境,情況将變得複雜無比。把龐大備援的Java鋸成一個個的Module,改進了Java SE 平台,使其可以适應不同大小的計算裝置,并改進其安全性,可維護性,提高性能。

JAVA9新特性(一)JAVA9新特性(一)

子產品文法

JAVA9新特性(一)JAVA9新特性(一)

< module-statement >是一個子產品語句。 子產品聲明中可以包含零個或多個子產品語句。 如果它存在,它可以是五種類型的語句之一:

導出語句(exports statement);

開放語句(opens statement);

需要語句(requires statement);

使用語句(uses statement);

提供語句(provides statement)。

子產品命名

子產品名稱可以是Java限定辨別符。 合法辨別符是一個或多個由點分隔的辨別符,例如policy,com.jdojo.common和com.jdojo.util。 如果子產品名稱中的任何部分不是有效的Java辨別符,則會發生編譯時錯誤。 例如,com.jdojo.common.1.0不是有效的子產品名稱,因為名稱中的1和0不是有效的Java辨別符。與包命名約定類似,使用反向域名模式為子產品提供唯一的名稱。 使用這個慣例,名為com.jdojo.common的最簡單的子產品可以聲明如下:

JAVA9新特性(一)JAVA9新特性(一)

子產品名稱不會隐藏具有相同名稱的變量,類型和包。 是以,可以擁有一個子產品以及具有相同名稱的變量,類型或包。 他們使用的上下文将區分哪個名稱是指什麼樣的實體。

在JDK 9中, open, module, requires, transitive, exports, opens, to, uses, provides 和 with是受限關鍵字。隻有當具體位置出現在子產品聲明中時,它們才具有特殊意義。 可以将它們用作程式中其他地方的辨別符。 例如,以下子產品聲明是有效的,即使它不使用直覺的子產品名稱:

JAVA9新特性(一)JAVA9新特性(一)

第一個子產品字被解釋為一個關鍵字,第二個是一個子產品名稱。

你可以在程式中的任何地方聲明一個名為module的變量:

JAVA9新特性(一)JAVA9新特性(一)

exports和requires

導出語句将子產品的指定包導出到所有子產品或編譯時和運作時的命名子產品清單。 它的兩種形式如下:

JAVA9新特性(一)JAVA9新特性(一)
JAVA9新特性(一)JAVA9新特性(一)

需要(require)語句聲明目前子產品與另一個子產品的依賴關系。 一個名為M的子產品中的“需要N”語句表示子產品M取決于(或讀取)子產品N。語句有以下形式:

JAVA9新特性(一)JAVA9新特性(一)

require語句中的靜态修飾符表示在編譯時的依賴是強制的,但在運作時是可選的。requires static N語句意味着子產品M取決于子產品N,子產品N必須在編譯時出現才能編譯子產品M,而在運作時存在子產品N是可選的。require語句中的transitive修飾符會導緻依賴于目前子產品的其他子產品具有隐式依賴性。假設有三個子產品P,Q和R,假設子產品Q包含requires transitive R語句,如果如果子產品P包含包含requires Q語句,這意味着子產品P隐含地取決于子產品R。

JAVA9新特性(一)JAVA9新特性(一)

下圖描述了兩個名為policy和claim的子產品之間的依賴關系。 policy子產品包含兩個名為pkg1和pkg2的包,它導出包pkg1,該包使用虛線邊界顯示,以将其與未導出的包pkg2區分開來。 claim子產品包含兩個件包pkg3和pkg4,它不導出包。 它聲明了對policy子產品的依賴。

JAVA9新特性(一)JAVA9新特性(一)
JAVA9新特性(一)JAVA9新特性(一)

open

如果你的子產品依賴于另一個子產品,則該子產品聲明要求知道子產品名稱。一些Java架構和工具(Spring,Hibernate…)在很大程度上依賴于反射來在運作時通路未導出的子產品的代碼

當子產品導出軟體包時,依賴于第一個子產品的其他子產品隻能通路導出的軟體包中的公共API。 在運作時,在子產品的所有軟體包上授予深入的反射通路權限(通路公共和私有API),可以聲明一個開放的子產品。

JAVA9新特性(一)JAVA9新特性(一)
JAVA9新特性(一)JAVA9新特性(一)

開放語句允許對所有子產品的反射通路指定的包或運作時指定的子產品清單。 其他子產品可以使用反射通路指定包中的所有類型以及這些類型的所有成員(私有和公共)。 開放語句如同exports形式

JAVA9新特性(一)JAVA9新特性(一)

導出語句允許僅在編譯時和運作時通路指定包的公共API,而打開語句允許在運作時使用反射通路指定包中的所有類型的公共和私有成員。

uses和provides

Java允許使用服務提供者和服務使用者分離的服務提供者機制。 JDK 9允許使用語句(uses statement)和提供語句(provides statement)實作其服務。

使用語句可以指定服務接口的名字,目前子產品就會發現它,使用 java.util.ServiceLoader類進行加載。格式如下:

JAVA9新特性(一)JAVA9新特性(一)
JAVA9新特性(一)JAVA9新特性(一)

com.jdojo.PrimeChecker是一個服務接口,其實作類将由其他子產品提供。 子產品M将使用java.util.ServiceLoader類來發現和加載此接口的實作。

提供語句指定服務接口的一個或多個服務提供程式實作類。 它采取以下形式:

JAVA9新特性(一)JAVA9新特性(一)

相同的子產品可以提供服務實作,可以發現和加載服務。 子產品還可以發現和加載一種服務,并為另一種服務提供實作。

JAVA9新特性(一)JAVA9新特性(一)

子產品的通路權限

子產品之間的關系被稱作readability(可讀性),代表一個子產品是否可以找到這個子產品檔案,并且讀入系統中(注意:并非代表可以通路其中的類型)。在實際的代碼,一個類型對于另外一個類型的調用,我們稱之為可通路性(Accessible),這意味着可以使用這個類型; 可通路性的前提是可讀性,換句話說,先有子產品可讀,然後才能再進一步檢測可通路性(安全)。

JAVA9新特性(一)JAVA9新特性(一)
JAVA9新特性(一)JAVA9新特性(一)

類加載器查找類方式改變

在這三個級别的Loader下面有一個統一Module 管理,用于控制和管理子產品間的依賴關系,可讀性,可通路性等。ClassLoader在Java 9中的類裝載邏輯和之前一樣,但是,通過子產品管理系統,ClassLoader.FindClass的能力,将被限制在readable&accessible的條件下,而不是之前的簡單的Public條件。

JAVA9新特性(一)JAVA9新特性(一)

PS:此文章為網絡糅合編寫,侵删。