本篇內(nèi)容主要講解“JDK9的新特性有哪些”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“JDK9的新特性有哪些”吧!
創(chuàng)新互聯(lián)專(zhuān)注于合浦企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站開(kāi)發(fā),商城網(wǎng)站定制開(kāi)發(fā)。合浦網(wǎng)站建設(shè)公司,為合浦等地區(qū)提供建站服務(wù)。全流程按需搭建網(wǎng)站,專(zhuān)業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專(zhuān)業(yè)和態(tài)度為您提供的服務(wù)
模塊系統(tǒng):模塊是一個(gè)包的容器,Java 9 最大的變化之一是引入了模塊系統(tǒng)(Jigsaw 項(xiàng)目)。
REPL (JShell):交互式編程環(huán)境。
HTTP 2 客戶(hù)端: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)行庫(kù)程序時(shí)選擇使用的 class 版本。
集合工廠(chǎng)方法:List,Set 和 Map 接口中,新的靜態(tài)工廠(chǎng)方法可以創(chuàng)建這些集合的不可變實(shí)例。
私有接口方法:在接口中使用private私有方法。我們可以使用 private 訪(fǎng)問(wèn)修飾符在接口中編寫(xiě)私有方法。
進(jìn)程 API: 改進(jìn)的 API 來(lái)控制和管理操作系統(tǒng)進(jìn)程。引進(jìn) java.lang.ProcessHandle 及其嵌套接口 Info 來(lái)讓開(kāi)發(fā)者逃離時(shí)常因?yàn)橐@取一個(gè)本地進(jìn)程的 PID 而不得不使用本地代碼的窘境。
改進(jìn)的 Stream API:改進(jìn)的 Stream API 添加了一些便利的方法,使流處理更容易,并使用收集器編寫(xiě)復(fù)雜的查詢(xún)。
改進(jìn) try-with-resources:如果你已經(jīng)有一個(gè)資源是 final 或等效于 final 變量,您可以在 try-with-resources 語(yǔ)句中使用該變量,而無(wú)需在 try-with-resources 語(yǔ)句中聲明一個(gè)新變量。
改進(jìn)的棄用注解 @Deprecated:注解 @Deprecated 可以標(biāo)記 Java API 狀態(tài),可以表示被標(biāo)記的 API 將會(huì)被移除,或者已經(jīng)破壞。
改進(jìn)鉆石操作符(Diamond Operator):匿名類(lèi)可以使用鉆石操作符(Diamond Operator)。
改進(jìn) Optional 類(lèi):java.util.Optional 添加了很多新的有用方法,Optional 可以直接轉(zhuǎn)為 stream。
多分辨率圖像 API:定義多分辨率圖像API,開(kāi)發(fā)者可以很容易的操作和展示不同分辨率的圖像了。
改進(jìn)的 CompletableFuture API: CompletableFuture 類(lèi)的異步機(jī)制可以在 ProcessHandle.onExit 方法退出時(shí)執(zhí)行操作。
輕量級(jí)的 JSON API:內(nèi)置了一個(gè)輕量級(jí)的JSON API
響應(yīng)式流(Reactive Streams) API: Java 9中引入了新的響應(yīng)式流 API 來(lái)支持 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ái)級(jí)模塊系統(tǒng)
Java 9 的定義功能是一套全新的模塊系統(tǒng)。當(dāng)代碼庫(kù)越來(lái)越大,創(chuàng)建復(fù)雜,盤(pán)根錯(cuò)節(jié)的“意大利面條式代碼”的幾率呈指數(shù)級(jí)的增長(zhǎng)。這時(shí)候就得面對(duì)兩個(gè)基礎(chǔ)的問(wèn)題: 很難真正地對(duì)代碼進(jìn)行封裝, 而系統(tǒng)并沒(méi)有對(duì)不同部分(也就是 JAR 文件)之間的依賴(lài)關(guān)系有個(gè)明確的概念。每一個(gè)公共類(lèi)都可以被類(lèi)路徑之下任何其它的公共類(lèi)所訪(fǎng)問(wèn)到, 這樣就會(huì)導(dǎo)致無(wú)意中使用了并不想被公開(kāi)訪(fǎng)問(wèn)的 API。此外,類(lèi)路徑本身也存在問(wèn)題: 你怎么知曉所有需要的 JAR 都已經(jīng)有了, 或者是不是會(huì)有重復(fù)的項(xiàng)呢? 模塊系統(tǒng)把這倆個(gè)問(wèn)題都給解決了。
模塊化的 JAR 文件都包含一個(gè)額外的模塊描述器。在這個(gè)模塊描述器中, 對(duì)其它模塊的依賴(lài)是通過(guò) “requires” 來(lái)表示的。另外, “exports” 語(yǔ)句控制著哪些包是可以被其它模塊訪(fǎng)問(wèn)到的。所有不被導(dǎo)出的包默認(rèn)都封裝在模塊的里面。如下是一個(gè)模塊描述器的示例,存在于 “module-info.java” 文件中:
module blog { exports com.pluralsight.blog; requires cms; }
請(qǐng)注意,兩個(gè)模塊都包含封裝的包,因?yàn)樗鼈儧](méi)有被導(dǎo)出(使用橙色盾牌可視化)。 沒(méi)有人會(huì)偶然地使用來(lái)自這些包中的類(lèi)。Java 平臺(tái)本身也使用自己的模塊系統(tǒng)進(jìn)行了模塊化。通過(guò)封裝 JDK 的內(nèi)部類(lèi),平臺(tái)更安全,持續(xù)改進(jìn)也更容易。
當(dāng)啟動(dòng)一個(gè)模塊化應(yīng)用時(shí), JVM 會(huì)驗(yàn)證是否所有的模塊都能使用,這基于 requires
語(yǔ)句——比脆弱的類(lèi)路徑邁進(jìn)了一大步。模塊允許你更好地強(qiáng)制結(jié)構(gòu)化封裝你的應(yīng)用并明確依賴(lài)。你可以在這個(gè)課程中學(xué)習(xí)更多關(guān)于 Java 9 中模塊工作的信息 。
2. Linking
當(dāng)你使用具有顯式依賴(lài)關(guān)系的模塊和模塊化的 JDK 時(shí),新的可能性出現(xiàn)了。你的應(yīng)用程序模塊現(xiàn)在將聲明其對(duì)其他應(yīng)用程序模塊的依賴(lài)以及對(duì)其所使用的 JDK 模塊的依賴(lài)。為什么不使用這些信息創(chuàng)建一個(gè)最小的運(yùn)行時(shí)環(huán)境,其中只包含運(yùn)行應(yīng)用程序所需的那些模塊呢? 這可以通過(guò) Java 9 中的新的 jlink 工具實(shí)現(xiàn)。你可以創(chuàng)建針對(duì)應(yīng)用程序進(jìn)行優(yōu)化的最小運(yùn)行時(shí)映像而不需要使用完全加載 JDK 安裝版本。
3. JShell : 交互式 Java REPL
許多語(yǔ)言已經(jīng)具有交互式編程環(huán)境,Java 現(xiàn)在加入了這個(gè)俱樂(lè)部。您可以從控制臺(tái)啟動(dòng) jshell ,并直接啟動(dòng)輸入和執(zhí)行 Java 代碼。 jshell 的即時(shí)反饋使它成為探索 API 和嘗試語(yǔ)言特性的好工具。
測(cè)試一個(gè) Java 正則表達(dá)式是一個(gè)很好的說(shuō)明 jshell 如何使您的生活更輕松的例子。 交互式 shell 還可以提供良好的教學(xué)環(huán)境以及提高生產(chǎn)力,您可以在此了解更多信息。在教人們?nèi)绾尉帉?xiě) Java 的過(guò)程中,不再需要解釋 “public static void main(String [] args)” 這句廢話(huà)。
4. 改進(jìn)的 Javadoc
有時(shí)一些小事情可以帶來(lái)很大的不同。你是否就像我一樣在一直使用 Google 來(lái)查找正確的 Javadoc 頁(yè)面呢? 這不再需要了。Javadoc 現(xiàn)在支持在 API 文檔中的進(jìn)行搜索。另外,Javadoc 的輸出現(xiàn)在符合兼容 HTML5 標(biāo)準(zhǔn)。此外,你會(huì)注意到,每個(gè) Javadoc 頁(yè)面都包含有關(guān) JDK 模塊類(lèi)或接口來(lái)源的信息。
5. 集合工廠(chǎng)方法
通常,您希望在代碼中創(chuàng)建一個(gè)集合(例如,List 或 Set ),并直接用一些元素填充它。 實(shí)例化集合,幾個(gè) “add” 調(diào)用,使得代碼重復(fù)。 Java 9,添加了幾種集合工廠(chǎng)方法:
Setints = Set.of( 1 , 2 , 3 ); List strings = List.of( "first" , "second" );
除了更短和更好閱讀之外,這些方法也可以避免您選擇特定的集合實(shí)現(xiàn)。 事實(shí)上,從工廠(chǎng)方法返回已放入數(shù)個(gè)元素的集合實(shí)現(xiàn)是高度優(yōu)化的。這是可能的,因?yàn)樗鼈兪遣豢勺兊模涸趧?chuàng)建后,繼續(xù)添加元素到這些集合會(huì)導(dǎo)致 “UnsupportedOperationException” 。
6. 改進(jìn)的 Stream API
長(zhǎng)期以來(lái),Stream API 都是 Java 標(biāo)準(zhǔn)庫(kù)最好的改進(jìn)之一。通過(guò)這套 API 可以在集合上建立用于轉(zhuǎn)換的申明管道。在 Java 9 中它會(huì)變得更好。Stream 接口中添加了 4 個(gè)新的方法:dropWhile, takeWhile, ofNullable。還有個(gè) iterate 方法的新重載方法,可以讓你提供一個(gè) Predicate (判斷條件)來(lái)指定什么時(shí)候結(jié)束迭代:
IntStream.iterate( 1 , i -> i < 100 , i -> i + 1 ).forEach(System.out::println);
第二個(gè)參數(shù)是一個(gè) Lambda,它會(huì)在當(dāng)前 IntStream 中的元素到達(dá) 100 的時(shí)候返回 true。因此這個(gè)簡(jiǎn)單的示例是向控制臺(tái)打印 1 到 99。
除了對(duì) Stream 本身的擴(kuò)展,Optional 和 Stream 之間的結(jié)合也得到了改進(jìn)?,F(xiàn)在可以通過(guò) Optional 的新方法 stram
將一個(gè) Optional 對(duì)象轉(zhuǎn)換為一個(gè)(可能是空的) Stream 對(duì)象:
Streams = Optional.of( 1 ).stream();
在組合復(fù)雜的 Stream 管道時(shí),將 Optional 轉(zhuǎn)換為 Stream 非常有用。
7. 私有接口方法
Java 8 為我們帶來(lái)了接口的默認(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,您可以向接口添加私有輔助方法來(lái)解決此問(wèn)題:
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)方法開(kāi)發(fā) API ,那么私有接口方法可能有助于構(gòu)建其實(shí)現(xiàn)。
8. HTTP/2
Java 9 中有新的方式來(lái)處理 HTTP 調(diào)用。這個(gè)遲到的特性用于代替老舊的 HttpURLConnection
API,并提供對(duì) WebSocket 和 HTTP/2 的支持。注意:新的 HttpClient API 在 Java 9 中以所謂的孵化器模塊交付。也就是說(shuō),這套 API 不能保證 100% 完成。不過(guò)你可以在 Java 9 中開(kāi)始使用這套 API:
HttpClient client = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder(URI.create( "http://www.google.com" )) .header( "User-Agent" , "Java" ) .GET() .build(); HttpResponseresp = client.send(req, HttpResponse.BodyHandler.asString());
HttpResponse
9.多版本兼容 JAR
我們最后要來(lái)著重介紹的這個(gè)特性對(duì)于庫(kù)的維護(hù)者而言是個(gè)特別好的消息。當(dāng)一個(gè)新版本的 Java 出現(xiàn)的時(shí)候,你的庫(kù)用戶(hù)要花費(fèi)數(shù)年時(shí)間才會(huì)切換到這個(gè)新的版本。這就意味著庫(kù)得去向后兼容你想要支持的最老的 Java 版本 (許多情況下就是 Java 6 或者 7)。這實(shí)際上意味著未來(lái)的很長(zhǎng)一段時(shí)間,你都不能在庫(kù)中運(yùn)用 Java 9 所提供的新特性。幸運(yùn)的是,多版本兼容 JAR 功能能讓你創(chuàng)建僅在特定版本的 Java 環(huán)境中運(yùn)行庫(kù)程序時(shí)選擇使用的 class 版本:
multirelease.jar ├── META-INF │ └── versions │ └── 9 │ └── multirelease │ └── Helper. class ├── multirelease ├── Helper. class └── Main. class
在上述場(chǎng)景中, multirelease.jar 可以在 Java 9 中使用, 不過(guò) Helper 這個(gè)類(lèi)使用的不是頂層的 multirelease.Helper 這個(gè) class, 而是處在“META-INF/versions/9”下面的這個(gè)。這是特別為 Java 9 準(zhǔn)備的 class 版本,可以運(yùn)用 Java 9 所提供的特性和庫(kù)。同時(shí),在早期的 Java 諸版本中使用這個(gè) JAR 也是能運(yùn)行的,因?yàn)檩^老版本的 Java 只會(huì)看到頂層的這個(gè) Helper 類(lèi)。
10.多分辨率圖像 API
Java 9 定義多分辨率圖像 API,開(kāi)發(fā)者可以很容易的操作和展示不同分辨率的圖像了。
以下是多分辨率圖像的主要操作方法:
Image getResolutionVariant(double destImageWidth, double destImageHeight)? 獲取特定分辨率的圖像變體-表示一張已知分辨率單位為DPI的特定尺寸大小的邏輯圖像,并且這張圖像是最佳的變體。。
List
實(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 { ListimgUrls = List.of("/upload/otherpic52/10823.png", "/upload/otherpic52/10824.png", "/upload/otherpic52/10825.png"); List images = new ArrayList (); for (String url : imgUrls) { images.add(ImageIO.read(new URL(url))); } // 讀取所有圖片 MultiResolutionImage multiResolutionImage = new BaseMultiResolutionImage(images.toArray(new Image[0])); // 獲取圖片的所有分辨率 List variants = multiResolutionImage.getResolutionVariants(); System.out.println("Total number of images: " + variants.size()); for (Image img : variants) { System.out.println(img); } // 根據(jù)不同尺寸獲取對(duì)應(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
Java 9 對(duì) CompletableFuture做了改進(jìn):
支持 delays 和 timeouts
提升了對(duì)子類(lèi)化的支持
新的工廠(chǎng)方法
支持 delays 和 timeouts
public CompletableFuturecompleteOnTimeout(T value, long timeout, TimeUnit unit)
在 timeout(單位在 java.util.concurrent.Timeunits units 中,比如 MILLISECONDS )前以給定的 value 完成這個(gè) CompletableFutrue。返回這個(gè) CompletableFutrue。
public CompletableFutureorTimeout(long timeout, TimeUnit unit)
如果沒(méi)有在給定的 timeout 內(nèi)完成,就以 java.util.concurrent.TimeoutException 完成這個(gè) CompletableFutrue,并返回這個(gè) CompletableFutrue。
增強(qiáng)了對(duì)子類(lèi)化的支持
做了許多改進(jìn)使得 CompletableFuture可以被更簡(jiǎn)單的繼承。比如,你也許想重寫(xiě)新的 public Executor defaultExecutor() 方法來(lái)代替默認(rèn)的 executor。
另一個(gè)新的使子類(lèi)化更容易的方法是:
public CompletableFuture newIncompleteFuture()
新的工廠(chǎng)方法
Java 8引入了 CompletableFuture completedFuture(U value)工廠(chǎng)方法來(lái)返回一個(gè)已經(jīng)以給定 value 完成了的 CompletableFuture。Java 9以 一個(gè)新的 CompletableFuture failedFuture(Throwable ex) 來(lái)補(bǔ)充了這個(gè)方法,可以返回一個(gè)以給定異常完成的 CompletableFuture。
除此以外,Java 9 引入了下面這對(duì) stage-oriented 工廠(chǎng)方法,返回完成的或異常完成的 completion stages:
CompletionStage completedStage(U value): 返回一個(gè)新的以指定 value 完成的CompletionStage,并且只支持 CompletionStage里的接口。
CompletionStage failedStage(Throwable ex): 返回一個(gè)新的以指定異常完成的CompletionStage,并且只支持 CompletionStage里的接口。
到此,相信大家對(duì)“JDK9的新特性有哪些”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!