1. 程式人生 > >Java9新特性

Java9新特性

jar lam span pro socket while clas module 擴展

Java9前幾天已經發布了,在此羅列下它的主要特性

1.Java模塊系統

  JDK9的核心變化就是引入了一種新的Java編程組件,也就是模塊。按照Oracle的說法,它是一個可命名的、自描述的代碼和數據集合。模塊技術的核心目標是減少Java應用和Java核心運行時環境的大小與復雜性。為此,JDK本身進行了模塊化,Oracle希望通過這種方式提升性能、安全性和可維護性。

  為了支持Java 9的模塊,引入一種新的模塊化JAR文件形式,按照這種形式會在其根目錄中包含一個module-info.class文件。Oracle同時提供了工具,允許我們組合和優化一組模塊,形成自定義的運行時鏡像(image),這樣的鏡像不必將整個Java運行時包含進來(模塊化處理)。模塊化所帶來的其他變化包括從Java運行時鏡像中移除了rt.jar和tools.jar

  模塊化的 JAR 文件都包含一個額外的模塊描述器。在這個模塊描述器中, 對其它模塊的依賴是通過 “requires” 來表示的。另外, “exports” 語句控制著哪些包是可以被其它模塊訪問到的。所有不被導出的包默認都封裝在模塊的裏面。如下是一個模塊描述器的示例,存在於 “module-info.java” 文件中:

1 module blog {
2   exports com.pluralsight.blog;
3  
4   requires cms;
5 }

我們可以如下展示模塊:

技術分享

請註意,兩個模塊都包含封裝的包,因為它們沒有被導出(使用橙色盾牌可視化)。 沒有人會偶然地使用來自這些包中的類。Java 平臺本身也使用自己的模塊系統進行了模塊化。通過封裝 JDK 的內部類,平臺更安全,持續改進也更容易。

當啟動一個模塊化應用時, JVM 會驗證是否所有的模塊都能使用,這基於 `requires` 語句——比脆弱的類路徑邁進了一大步。模塊允許你更好地強制結構化封裝你的應用並明確依賴。你可以在這個課程中學習更多關於 Java 9 中模塊工作的信息

2.Link

當你使用具有顯式依賴關系的模塊和模塊化的 JDK 時,新的可能性出現了。你的應用程序模塊現在將聲明其對其他應用程序模塊的依賴以及對其所使用的 JDK 模塊的依賴。為什麽不使用這些信息創建一個最小的運行時環境,其中只包含運行應用程序所需的那些模塊呢? 這可以通過 Java 9 中的新的 jlink 工具實現。你可以創建針對應用程序進行優化的最小運行時映像而不需要使用完全加載 JDK 安裝版本

3.JShell : 交互式 Java REPL

許多語言已經具有交互式編程環境,Java 現在加入了這個俱樂部。您可以從控制臺啟動 jshell ,並直接啟動輸入和執行 Java 代碼。 jshell 的即時反饋使它成為探索 API 和嘗試語言特性的好工具。

技術分享

測試一個 Java 正則表達式是一個很好的說明 jshell 如何使您的生活更輕松的例子。 交互式 shell 還可以提供良好的教學環境以及提高生產力,您可以在此了解更多信息。在教人們如何編寫 Java 的過程中,不再需要解釋 “public static void main(String [] args)” 這句廢話

這個命令行環境為Java平臺帶來了讀入-求值-打印-循環(Read-Eval-Print-Loop,REPL)功能。它的目的在於以即時結果和反饋的形式,簡化原型的實現並幫助我們探索語言在編碼時的可選項

4. 改進的 Javadoc

有時一些小事情可以帶來很大的不同。你是否就像我一樣在一直使用 Google 來查找正確的 Javadoc 頁面呢? 這不再需要了。Javadoc 現在支持在 API 文檔中的進行搜索。另外,Javadoc 的輸出現在符合兼容 HTML5 標準。此外,你會註意到,每個 Javadoc 頁面都包含有關 JDK 模塊類或接口來源的信息。

技術分享

5. 集合工廠方法

通常,您希望在代碼中創建一個集合(例如,List 或 Set ),並直接用一些元素填充它。 實例化集合,幾個 “add” 調用,使得代碼重復。 Java 9,添加了幾種集合工廠方法:

Set<Integer> ints = Set.of(1, 2, 3);
List<String> strings = List.of("first", "second");

除了更短和更好閱讀之外,這些方法也可以避免您選擇特定的集合實現。 事實上,從工廠方法返回已放入數個元素的集合實現是高度優化的。這是可能的,因為它們是不可變的:在創建後,繼續添加元素到這些集合會導致 “UnsupportedOperationException”

6. 改進的 Stream API

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

IntStream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);

第二個參數是一個 Lambda,它會在當前 IntStream 中的元素到達 100 的時候返回 true。因此這個簡單的示例是向控制臺打印 1 到 99。

除了對 Stream 本身的擴展,Optional 和 Stream 之間的結合也得到了改進。現在可以通過 Optional 的新方法 `stram` 將一個 Optional 對象轉換為一個(可能是空的) Stream 對象:

7.私有接口方法

Java 8 為我們帶來了接口的默認方法。 接口現在也可以包含行為,而不僅僅是方法簽名。 但是,如果在接口上有幾個默認方法,代碼幾乎相同,會發生什麽情況? 通常,您將重構這些方法,調用一個可復用的私有方法。 但默認方法不能是私有的。 將復用代碼創建為一個默認方法不是一個解決方案,因為該輔助方法會成為公共API的一部分。 使用 Java 9,您可以向接口添加私有輔助方法來解決此問題:

public interface MyInterface {
 
    void normalInterfaceMethod();
 
    default void interfaceMethodWithDefault() {  init(); }
 
    default void anotherDefaultMethod() { init(); }
 
    // This method is not part of the public API exposed by MyInterface
    private void init() { System.out.println("Initializing"); }
}

如果您使用默認方法開發 API ,那麽私有接口方法可能有助於構建其實現

8.HTTP/2

Java 9 中有新的方式來處理 HTTP 調用。這個遲到的特性用於代替老舊的 `HttpURLConnection` API,並提供對 WebSocket 和 HTTP/2 的支持。註意:新的 HttpClient API 在 Java 9 中以所謂的孵化器模塊交付。也就是說,這套 API 不能保證 100% 完成。不過你可以在 Java 9 中開始使用這套 API:

HttpClient client = HttpClient.newHttpClient();
 
HttpRequest req = HttpRequest.newBuilder(URI.create("http://www.google.com"))
              .header("User-Agent","Java")
              .GET()
              .build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString());

HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString());
除了這個簡單的請求/響應模型之外,HttpClient 還提供了新的 API 來處理 HTTP/2 的特性,比如流和服務端推送

HTTP/2只是作為Java 9的一個孵化模塊(incubator module)提供的

9. 多版本兼容 JAR

我們最後要來著重介紹的這個特性對於庫的維護者而言是個特別好的消息。當一個新版本的 Java 出現的時候,你的庫用戶要花費數年時間才會切換到這個新的版本。這就意味著庫得去向後兼容你想要支持的最老的 Java 版本 (許多情況下就是 Java 6 或者 7)。這實際上意味著未來的很長一段時間,你都不能在庫中運用 Java 9 所提供的新特性。幸運的是,多版本兼容 JAR 功能能讓你創建僅在特定版本的 Java 環境中運行庫程序時選擇使用的 class 版本:

multirelease.jar
├── META-INF
│   └── versions
│       └── 9
│           └── multirelease
│               └── Helper.class
├── multirelease
    ├── Helper.class
    └── Main.class

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

Java9新特性