您好,登錄后才能下訂單哦!
本篇內容主要講解“JDK9的新特性有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JDK9的新特性有哪些”吧!
模塊系統:模塊是一個包的容器,Java 9 最大的變化之一是引入了模塊系統(Jigsaw 項目)。
REPL (JShell):交互式編程環境。
HTTP 2 客戶端:HTTP/2標準是HTTP協議的最新版本,新的 HTTPClient API 支持 WebSocket 和 HTTP2 流以及服務器推送特性。
改進的 Javadoc:Javadoc 現在支持在 API 文檔中的進行搜索。另外,Javadoc 的輸出現在符合兼容 HTML5 標準。
多版本兼容 JAR 包:多版本兼容 JAR 功能能讓你創建僅在特定版本的 Java 環境中運行庫程序時選擇使用的 class 版本。
集合工廠方法:List,Set 和 Map 接口中,新的靜態工廠方法可以創建這些集合的不可變實例。
私有接口方法:在接口中使用private私有方法。我們可以使用 private 訪問修飾符在接口中編寫私有方法。
進程 API: 改進的 API 來控制和管理操作系統進程。引進 java.lang.ProcessHandle 及其嵌套接口 Info 來讓開發者逃離時常因為要獲取一個本地進程的 PID 而不得不使用本地代碼的窘境。
改進的 Stream API:改進的 Stream API 添加了一些便利的方法,使流處理更容易,并使用收集器編寫復雜的查詢。
改進 try-with-resources:如果你已經有一個資源是 final 或等效于 final 變量,您可以在 try-with-resources 語句中使用該變量,而無需在 try-with-resources 語句中聲明一個新變量。
改進的棄用注解 @Deprecated:注解 @Deprecated 可以標記 Java API 狀態,可以表示被標記的 API 將會被移除,或者已經破壞。
改進鉆石操作符(Diamond Operator) :匿名類可以使用鉆石操作符(Diamond Operator)。
改進 Optional 類:java.util.Optional 添加了很多新的有用方法,Optional 可以直接轉為 stream。
多分辨率圖像 API:定義多分辨率圖像API,開發者可以很容易的操作和展示不同分辨率的圖像了。
改進的 CompletableFuture API : CompletableFuture 類的異步機制可以在 ProcessHandle.onExit 方法退出時執行操作。
輕量級的 JSON API:內置了一個輕量級的JSON API
響應式流(Reactive Streams) API: Java 9中引入了新的響應式流 API 來支持 Java 9 中的響應式編程。
更多的新特性可以參閱官網:What's New in JDK 9
JDK 9 下載地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk9-doc-downloads-3850606.html
在關于 Java 9 文章的實例,我們均使用 jdk 1.9 環境,你可以使用以下命令查看當前 jdk 的版本:
$ java -version java version "9-ea" Java(TM) SE Runtime Environment (build 9-ea+163) Java HotSpot(TM) 64-Bit Server VM (build 9-ea+163, mixed mode)
1. Java 平臺級模塊系統
Java 9 的定義功能是一套全新的模塊系統。當代碼庫越來越大,創建復雜,盤根錯節的“意大利面條式代碼”的幾率呈指數級的增長。這時候就得面對兩個基礎的問題: 很難真正地對代碼進行封裝, 而系統并沒有對不同部分(也就是 JAR 文件)之間的依賴關系有個明確的概念。每一個公共類都可以被類路徑之下任何其它的公共類所訪問到, 這樣就會導致無意中使用了并不想被公開訪問的 API。此外,類路徑本身也存在問題: 你怎么知曉所有需要的 JAR 都已經有了, 或者是不是會有重復的項呢? 模塊系統把這倆個問題都給解決了。
模塊化的 JAR 文件都包含一個額外的模塊描述器。在這個模塊描述器中, 對其它模塊的依賴是通過 “requires” 來表示的。另外, “exports” 語句控制著哪些包是可以被其它模塊訪問到的。所有不被導出的包默認都封裝在模塊的里面。如下是一個模塊描述器的示例,存在于 “module-info.java” 文件中:
module blog { exports com.pluralsight.blog; requires cms; }
請注意,兩個模塊都包含封裝的包,因為它們沒有被導出(使用橙色盾牌可視化)。 沒有人會偶然地使用來自這些包中的類。Java 平臺本身也使用自己的模塊系統進行了模塊化。通過封裝 JDK 的內部類,平臺更安全,持續改進也更容易。
當啟動一個模塊化應用時, JVM 會驗證是否所有的模塊都能使用,這基于 requires
語句——比脆弱的類路徑邁進了一大步。模塊允許你更好地強制結構化封裝你的應用并明確依賴。你可以在這個課程中學習更多關于 Java 9 中模塊工作的信息 。
2. Linking
當你使用具有顯式依賴關系的模塊和模塊化的 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)” 這句廢話。
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" );</pre>
除了更短和更好閱讀之外,這些方法也可以避免您選擇特定的集合實現。 事實上,從工廠方法返回已放入數個元素的集合實現是高度優化的。這是可能的,因為它們是不可變的:在創建后,繼續添加元素到這些集合會導致 “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);</pre>
第二個參數是一個 Lambda,它會在當前 IntStream 中的元素到達 100 的時候返回 true。因此這個簡單的示例是向控制臺打印 1 到 99。
除了對 Stream 本身的擴展,Optional 和 Stream 之間的結合也得到了改進。現在可以通過 Optional 的新方法 stram
將一個 Optional 對象轉換為一個(可能是空的) Stream 對象:
Stream<Integer> s = Optional.of( 1 ).stream();</pre>
在組合復雜的 Stream 管道時,將 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 的特性,比如流和服務端推送。
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 類。
10.多分辨率圖像 API
Java 9 定義多分辨率圖像 API,開發者可以很容易的操作和展示不同分辨率的圖像了。
以下是多分辨率圖像的主要操作方法:
Image getResolutionVariant(double destImageWidth, double destImageHeight) ? 獲取特定分辨率的圖像變體-表示一張已知分辨率單位為DPI的特定尺寸大小的邏輯圖像,并且這張圖像是最佳的變體。。
List<Image> getResolutionVariants() ? 返回可讀的分辨率的圖像變體列表。
實例
import java.io.IOException; import java.net.URL; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import java.awt.Image; import java.awt.image.MultiResolutionImage; import java.awt.image.BaseMultiResolutionImage; import javax.imageio.ImageIO; public class Tester { public static void main(String[] args) throws IOException, MalformedURLException { List<String> imgUrls = List.of("https://cache.yisu.com/upload/information/20210524/357/10823.png", "https://cache.yisu.com/upload/information/20210524/357/10824.png", "https://cache.yisu.com/upload/information/20210524/357/10825.png"); List<Image> images = new ArrayList<Image>(); for (String url : imgUrls) { images.add(ImageIO.read(new URL(url))); } // 讀取所有圖片 MultiResolutionImage multiResolutionImage = new BaseMultiResolutionImage(images.toArray(new Image[0])); // 獲取圖片的所有分辨率 List<Image> variants = multiResolutionImage.getResolutionVariants(); System.out.println("Total number of images: " + variants.size()); for (Image img : variants) { System.out.println(img); } // 根據不同尺寸獲取對應的圖像分辨率 Image variant1 = multiResolutionImage.getResolutionVariant(156, 45); System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 156, 45, variant1.getWidth(null), variant1.getHeight(null)); Image variant2 = multiResolutionImage.getResolutionVariant(311, 89); System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 311, 89, variant2.getWidth(null), variant2.getHeight(null)); Image variant3 = multiResolutionImage.getResolutionVariant(622, 178); System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 622, 178, variant3.getWidth(null), variant3.getHeight(null)); Image variant4 = multiResolutionImage.getResolutionVariant(300, 300); System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 300, 300, variant4.getWidth(null), variant4.getHeight(null)); } }
11.CompletableFuture API
Java 8 引入了 CompletableFuture<T>*類,可能是 java.util.concurrent.Future<T> 明確的完成版(設置了它的值和狀態),也可能被用作java.util.concurrent.CompleteStage 。支持 future 完成時觸發一些依賴的函數和動作。Java 9 引入了一些CompletableFuture 的改進:
Java 9 對 CompletableFuture做了改進:
支持 delays 和 timeouts
提升了對子類化的支持
新的工廠方法
支持 delays 和 timeouts
public CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)
在 timeout(單位在 java.util.concurrent.Timeunits units 中,比如 MILLISECONDS )前以給定的 value 完成這個 CompletableFutrue。返回這個 CompletableFutrue。
public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)</pre>
如果沒有在給定的 timeout 內完成,就以 java.util.concurrent.TimeoutException 完成這個 CompletableFutrue,并返回這個 CompletableFutrue。
增強了對子類化的支持
做了許多改進使得 CompletableFuture可以被更簡單的繼承。比如,你也許想重寫新的 public Executor defaultExecutor() 方法來代替默認的 executor。
另一個新的使子類化更容易的方法是:
public <U> CompletableFuture<U> newIncompleteFuture()</pre
新的工廠方法
Java 8引入了 <U> CompletableFuture<U> completedFuture(U value)工廠方法來返回一個已經以給定 value 完成了的 CompletableFuture。Java 9以 一個新的 <U> CompletableFuture<U> failedFuture(Throwable ex) 來補充了這個方法,可以返回一個以給定異常完成的 CompletableFuture。
除此以外,Java 9 引入了下面這對 stage-oriented 工廠方法,返回完成的或異常完成的 completion stages:
<U> CompletionStage<U> completedStage(U value): 返回一個新的以指定 value 完成的CompletionStage ,并且只支持 CompletionStage 里的接口。
<U> CompletionStage<U> failedStage(Throwable ex): 返回一個新的以指定異常完成的CompletionStage ,并且只支持 CompletionStage 里的接口。
到此,相信大家對“JDK9的新特性有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。