溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JDK9的新特性有哪些

發(fā)布時(shí)間:2021-10-23 16:07:23 來源:億速云 閱讀:129 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“JDK9的新特性有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“JDK9的新特性有哪些”吧!

Java 9 新特性

  • 模塊系統(tǒng):模塊是一個(gè)包的容器,Java 9 最大的變化之一是引入了模塊系統(tǒng)(Jigsaw 項(xiàng)目)。

  • REPL (JShell):交互式編程環(huán)境。

  • HTTP 2 客戶端:HTTP/2標(biāo)準(zhǔn)是HTTP協(xié)議的最新版本,新的 HTTPClient API 支持 WebSocket 和 HTTP2 流以及服務(wù)器推送特性。

  • 改進(jìn)的 Javadoc:Javadoc 現(xiàn)在支持在 API 文檔中的進(jìn)行搜索。另外,Javadoc 的輸出現(xiàn)在符合兼容 HTML5 標(biāo)準(zhǔn)。

  • 多版本兼容 JAR 包:多版本兼容 JAR 功能能讓你創(chuàng)建僅在特定版本的 Java 環(huán)境中運(yùn)行庫程序時(shí)選擇使用的 class 版本。

  • 集合工廠方法:List,Set 和 Map 接口中,新的靜態(tài)工廠方法可以創(chuàng)建這些集合的不可變實(shí)例。

  • 私有接口方法:在接口中使用private私有方法。我們可以使用 private 訪問修飾符在接口中編寫私有方法。

  • 進(jìn)程 API: 改進(jìn)的 API 來控制和管理操作系統(tǒng)進(jìn)程。引進(jìn) java.lang.ProcessHandle 及其嵌套接口 Info 來讓開發(fā)者逃離時(shí)常因?yàn)橐@取一個(gè)本地進(jìn)程的 PID 而不得不使用本地代碼的窘境。

  • 改進(jìn)的 Stream API:改進(jìn)的 Stream API 添加了一些便利的方法,使流處理更容易,并使用收集器編寫復(fù)雜的查詢。

  • 改進(jìn) try-with-resources:如果你已經(jīng)有一個(gè)資源是 final 或等效于 final 變量,您可以在 try-with-resources 語句中使用該變量,而無需在 try-with-resources 語句中聲明一個(gè)新變量。

  • 改進(jìn)的棄用注解 @Deprecated:注解 @Deprecated 可以標(biāo)記 Java API 狀態(tài),可以表示被標(biāo)記的 API 將會(huì)被移除,或者已經(jīng)破壞。

  • 改進(jìn)鉆石操作符(Diamond Operator) :匿名類可以使用鉆石操作符(Diamond Operator)。

  • 改進(jìn) Optional 類:java.util.Optional 添加了很多新的有用方法,Optional 可以直接轉(zhuǎn)為 stream。

  • 多分辨率圖像 API:定義多分辨率圖像API,開發(fā)者可以很容易的操作和展示不同分辨率的圖像了。

  • 改進(jìn)的 CompletableFuture API : CompletableFuture 類的異步機(jī)制可以在 ProcessHandle.onExit 方法退出時(shí)執(zhí)行操作。

  • 輕量級的 JSON API:內(nèi)置了一個(gè)輕量級的JSON API

  • 響應(yīng)式流(Reactive Streams) API: Java 9中引入了新的響應(yīng)式流 API 來支持 Java 9 中的響應(yīng)式編程。

更多的新特性可以參閱官網(wǎng):What's New in JDK 9

JDK 9 下載地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk9-doc-downloads-3850606.html

在關(guān)于 Java 9 文章的實(shí)例,我們均使用 jdk 1.9 環(huán)境,你可以使用以下命令查看當(dāng)前 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 平臺級模塊系統(tǒng)

Java 9 的定義功能是一套全新的模塊系統(tǒng)。當(dāng)代碼庫越來越大,創(chuàng)建復(fù)雜,盤根錯(cuò)節(jié)的“意大利面條式代碼”的幾率呈指數(shù)級的增長。這時(shí)候就得面對兩個(gè)基礎(chǔ)的問題: 很難真正地對代碼進(jìn)行封裝, 而系統(tǒng)并沒有對不同部分(也就是 JAR 文件)之間的依賴關(guān)系有個(gè)明確的概念。每一個(gè)公共類都可以被類路徑之下任何其它的公共類所訪問到, 這樣就會(huì)導(dǎo)致無意中使用了并不想被公開訪問的 API。此外,類路徑本身也存在問題: 你怎么知曉所有需要的 JAR 都已經(jīng)有了, 或者是不是會(huì)有重復(fù)的項(xiàng)呢? 模塊系統(tǒng)把這倆個(gè)問題都給解決了。

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

module blog {
 exports com.pluralsight.blog;

 requires cms;
}

請注意,兩個(gè)模塊都包含封裝的包,因?yàn)樗鼈儧]有被導(dǎo)出(使用橙色盾牌可視化)。 沒有人會(huì)偶然地使用來自這些包中的類。Java 平臺本身也使用自己的模塊系統(tǒng)進(jìn)行了模塊化。通過封裝 JDK 的內(nèi)部類,平臺更安全,持續(xù)改進(jìn)也更容易。

當(dāng)啟動(dòng)一個(gè)模塊化應(yīng)用時(shí), JVM 會(huì)驗(yàn)證是否所有的模塊都能使用,這基于 requires 語句——比脆弱的類路徑邁進(jìn)了一大步。模塊允許你更好地強(qiáng)制結(jié)構(gòu)化封裝你的應(yīng)用并明確依賴。你可以在這個(gè)課程中學(xué)習(xí)更多關(guān)于 Java 9 中模塊工作的信息 。

2. Linking

當(dāng)你使用具有顯式依賴關(guān)系的模塊和模塊化的 JDK 時(shí),新的可能性出現(xiàn)了。你的應(yīng)用程序模塊現(xiàn)在將聲明其對其他應(yīng)用程序模塊的依賴以及對其所使用的 JDK 模塊的依賴。為什么不使用這些信息創(chuàng)建一個(gè)最小的運(yùn)行時(shí)環(huán)境,其中只包含運(yùn)行應(yīng)用程序所需的那些模塊呢? 這可以通過 Java 9 中的新的 jlink 工具實(shí)現(xiàn)。你可以創(chuàng)建針對應(yīng)用程序進(jìn)行優(yōu)化的最小運(yùn)行時(shí)映像而不需要使用完全加載 JDK 安裝版本。

3. JShell : 交互式 Java REPL

許多語言已經(jīng)具有交互式編程環(huán)境,Java 現(xiàn)在加入了這個(gè)俱樂部。您可以從控制臺啟動(dòng) jshell ,并直接啟動(dòng)輸入和執(zhí)行 Java 代碼。 jshell 的即時(shí)反饋使它成為探索 API 和嘗試語言特性的好工具。

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

4. 改進(jìn)的 Javadoc

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

5. 集合工廠方法

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

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

除了更短和更好閱讀之外,這些方法也可以避免您選擇特定的集合實(shí)現(xiàn)。 事實(shí)上,從工廠方法返回已放入數(shù)個(gè)元素的集合實(shí)現(xiàn)是高度優(yōu)化的。這是可能的,因?yàn)樗鼈兪遣豢勺兊模涸趧?chuàng)建后,繼續(xù)添加元素到這些集合會(huì)導(dǎo)致 “UnsupportedOperationException” 。

6. 改進(jìn)的 Stream API

長期以來,Stream API 都是 Java 標(biāo)準(zhǔn)庫最好的改進(jìn)之一。通過這套 API 可以在集合上建立用于轉(zhuǎn)換的申明管道。在 Java 9 中它會(huì)變得更好。Stream 接口中添加了 4 個(gè)新的方法:dropWhile, takeWhile, ofNullable。還有個(gè) iterate 方法的新重載方法,可以讓你提供一個(gè) Predicate (判斷條件)來指定什么時(shí)候結(jié)束迭代:

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

第二個(gè)參數(shù)是一個(gè) Lambda,它會(huì)在當(dāng)前 IntStream 中的元素到達(dá) 100 的時(shí)候返回 true。因此這個(gè)簡單的示例是向控制臺打印 1 到 99。

除了對 Stream 本身的擴(kuò)展,Optional 和 Stream 之間的結(jié)合也得到了改進(jìn)。現(xiàn)在可以通過 Optional 的新方法 stram 將一個(gè) Optional 對象轉(zhuǎn)換為一個(gè)(可能是空的) Stream 對象:

Stream<Integer> s = Optional.of( 1 ).stream();</pre>

在組合復(fù)雜的 Stream 管道時(shí),將 Optional 轉(zhuǎn)換為 Stream 非常有用。

7. 私有接口方法

Java 8 為我們帶來了接口的默認(rèn)方法。 接口現(xiàn)在也可以包含行為,而不僅僅是方法簽名。 但是,如果在接口上有幾個(gè)默認(rèn)方法,代碼幾乎相同,會(huì)發(fā)生什么情況? 通常,您將重構(gòu)這些方法,調(diào)用一個(gè)可復(fù)用的私有方法。 但默認(rèn)方法不能是私有的。 將復(fù)用代碼創(chuàng)建為一個(gè)默認(rèn)方法不是一個(gè)解決方案,因?yàn)樵撦o助方法會(huì)成為公共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" ); 
 }
}

如果您使用默認(rèn)方法開發(fā) API ,那么私有接口方法可能有助于構(gòu)建其實(shí)現(xiàn)。

8. HTTP/2

Java 9 中有新的方式來處理 HTTP 調(diào)用。這個(gè)遲到的特性用于代替老舊的 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()); 除了這個(gè)簡單的請求/響應(yīng)模型之外,HttpClient 還提供了新的 API 來處理 HTTP/2 的特性,比如流和服務(wù)端推送。

9.多版本兼容 JAR

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

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

在上述場景中, multirelease.jar 可以在 Java 9 中使用, 不過 Helper 這個(gè)類使用的不是頂層的 multirelease.Helper 這個(gè) class, 而是處在“META-INF/versions/9”下面的這個(gè)。這是特別為 Java 9 準(zhǔn)備的 class 版本,可以運(yùn)用 Java 9 所提供的特性和庫。同時(shí),在早期的 Java 諸版本中使用這個(gè) JAR 也是能運(yùn)行的,因?yàn)檩^老版本的 Java 只會(huì)看到頂層的這個(gè) Helper 類。

10.多分辨率圖像 API

Java 9 定義多分辨率圖像 API,開發(fā)者可以很容易的操作和展示不同分辨率的圖像了。

以下是多分辨率圖像的主要操作方法:

  • Image getResolutionVariant(double destImageWidth, double destImageHeight) ? 獲取特定分辨率的圖像變體-表示一張已知分辨率單位為DPI的特定尺寸大小的邏輯圖像,并且這張圖像是最佳的變體。。

  • List<Image> getResolutionVariants() ? 返回可讀的分辨率的圖像變體列表。

實(shí)例

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);
 }

 // 根據(jù)不同尺寸獲取對應(yīng)的圖像分辨率
 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> 明確的完成版(設(shè)置了它的值和狀態(tài)),也可能被用作java.util.concurrent.CompleteStage 。支持 future 完成時(shí)觸發(fā)一些依賴的函數(shù)和動(dòng)作。Java 9 引入了一些CompletableFuture 的改進(jìn):

Java 9 對 CompletableFuture做了改進(jìn):

  • 支持 delays 和 timeouts

  • 提升了對子類化的支持

  • 新的工廠方法

支持 delays 和 timeouts

public CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)

在 timeout(單位在 java.util.concurrent.Timeunits units 中,比如 MILLISECONDS )前以給定的 value 完成這個(gè) CompletableFutrue。返回這個(gè) CompletableFutrue。

public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)</pre>

如果沒有在給定的 timeout 內(nèi)完成,就以 java.util.concurrent.TimeoutException 完成這個(gè) CompletableFutrue,并返回這個(gè) CompletableFutrue。

增強(qiáng)了對子類化的支持

做了許多改進(jìn)使得 CompletableFuture可以被更簡單的繼承。比如,你也許想重寫新的 public Executor defaultExecutor() 方法來代替默認(rèn)的 executor。

另一個(gè)新的使子類化更容易的方法是:

public <U> CompletableFuture<U> newIncompleteFuture()</pre

新的工廠方法

Java 8引入了 <U> CompletableFuture<U> completedFuture(U value)工廠方法來返回一個(gè)已經(jīng)以給定 value 完成了的 CompletableFuture。Java 9以 一個(gè)新的 <U> CompletableFuture<U> failedFuture(Throwable ex) 來補(bǔ)充了這個(gè)方法,可以返回一個(gè)以給定異常完成的 CompletableFuture。

除此以外,Java 9 引入了下面這對 stage-oriented 工廠方法,返回完成的或異常完成的 completion stages:

  • <U> CompletionStage<U> completedStage(U value): 返回一個(gè)新的以指定 value 完成的CompletionStage ,并且只支持 CompletionStage 里的接口。

  • <U> CompletionStage<U> failedStage(Throwable ex): 返回一個(gè)新的以指定異常完成的CompletionStage ,并且只支持 CompletionStage 里的接口。

到此,相信大家對“JDK9的新特性有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jdk
AI