【譯】使用示例帶你提前了解 Java 9 中的新特性

Java 作為 Android 的基礎(chǔ)編程語(yǔ)言,每一次迭代也是備受安卓開發(fā)人員的關(guān)注。這不,Oracle 公司在今年即將發(fā)布 Java 9 正式版,一些新的特性和改進(jìn)很是值得期待。

周末時(shí)間,拜讀了國(guó)外的一個(gè) Java 大牛寫的有關(guān) Java SE 9 的新功能介紹,簡(jiǎn)明扼要,示例得當(dāng)。于是,一時(shí)興起,以拙劣的英語(yǔ)水平磕磕絆絆翻譯至此,供大家了解一番。

作者:「Rambabu Posa」,一個(gè)具有 11 年豐富開發(fā)經(jīng)驗(yàn)的技術(shù)牛人。

英文出處:Java 9 Features with Examples

Oracle 公司即將在 2017 年 3 月底正式發(fā)布 Java SE 9。在這篇文章,我將使用一些示例簡(jiǎn)明扼要地闡述 Java 9 的新特性。當(dāng)然,也是時(shí)候去了解一下。

1. Java 9 PEPK(JShell)


Oracle 公司(Java Library 開發(fā)者)新引進(jìn)一個(gè)代表 Java Shell 的稱之為 “jshell” 或者 REPL(Read Evaluate Print Loop)的新工具。該工具可以被用來執(zhí)行和測(cè)試任何 Java 中的結(jié)構(gòu),如 class,interface,enum,object,statements 等。使用非常簡(jiǎn)單。

JDK 9 EA(Early Access)下載地址:https://jdk9.java.net/download/

G:\>jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro


jshell> int a = 10
a ==> 10

jshell> System.out.println("a value = " + a )
a value = 10

有關(guān) REPL 工具的更多信息,可訪問 Java 9 REPL Basics (Part-1)Java 9 REPL Features (Part-2).

2. 不可變集合類的工廠方法


Oracle 公司引入一些方便使用的工廠方法,用于創(chuàng)建不可變集合 List,Set,Map 和 Map.Entry 對(duì)象。這些高效實(shí)用的方法可用來創(chuàng)建空或者非空集合對(duì)象。

在 Java SE 8 和更早版本中,我們常用類似 unmodifiableXXX 的集合類方法創(chuàng)建不可變集合對(duì)象。舉個(gè)例子,比如我們想創(chuàng)建一個(gè)不可變的 List 對(duì)象,可能使用到 Collections.unmodifiableList 方法。

然而,這些 Collections.unmodifiableXXX 方法顯得非常冗長(zhǎng)乏味。為了克服這些缺陷,Oracle 公司給 List、Set 和 Map 接口分別添加了兩個(gè)更加實(shí)用的方法。

List 和 Set 接口使用 of() 方法創(chuàng)建一個(gè)空或者非空的不可變 List 或 Set 對(duì)象,如:

空 List 示例

List immutableList = List.of();

非空 List 示例

List immutableList = List.of("one","two","three");

Map 分別有兩個(gè)方法用于創(chuàng)建不可變 Map 對(duì)象和不可變 Map.Entry 對(duì)象:of()ofEntries()

空 Map 示例

jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}

非空 Map 示例

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}

更多有關(guān)這些實(shí)用方法的信息,可以通過這些鏈接查詢:

3. 接口中的私有方法


在 Java 8 中,我們可以在接口中使用默認(rèn)或者靜態(tài)方法提供一些實(shí)現(xiàn)方式,但是不能創(chuàng)建私有方法。

為了避免冗余代碼和提高重用性,Oracle 公司準(zhǔn)備在 Java SE 9 接口中引入私有方法。也就是說從 Java SE 9 開始,我們也能夠在接口類中使用 ‘private’ 關(guān)鍵字寫私有化方法和私有化靜態(tài)方法。

接口中的私有方法與 class 類中的私有方法在寫法上并無差異,如:

public interface Card{

  private Long createCardID(){
    // Method implementation goes here.
  }

  private static void displayCardDetails(){
    // Method implementation goes here.
  }

}

有關(guān)接口私有方法新特性的更多信息,可訪問我的初體驗(yàn)之:Java 9 Private methods in Interface

4. Java 9 Module System


Java 9 新特性中最大的一個(gè)變化就是 Module System。Oracle 公司將引入如下特性作為 Jigsaw Project 的一部分:

  • Modular JDK
  • Modular Java Source Code
  • Modular Run-time Images
  • Encapsulate Java Internal APIs
  • Java Platform Module System

Java SE 9 版本之前,我們使用 Monolithic Jars 來開發(fā)基于 Java 語(yǔ)言的應(yīng)用程序。這種體系架構(gòu)有許多局限性和缺點(diǎn)。為了避免這些缺陷,Java SE 9 迎來了 Module System。

JDK 9 包含有 92 個(gè) modules(當(dāng)然也可能在最終發(fā)布版中有所變化)。我們可以使用 JDK Modules,也能創(chuàng)建我們自己的 modules,如:

簡(jiǎn)單 Module 示例

module com.foo.bar { }

這里我們使用 module 關(guān)鍵字創(chuàng)建了一個(gè)簡(jiǎn)單的 module。每個(gè) module 都有一個(gè)名字,對(duì)應(yīng)代碼和其它一些資源。

想了解更多有關(guān)這個(gè)新體系架構(gòu)和親自動(dòng)手體驗(yàn)的話,可以參考這里我的體驗(yàn)之:

  • Java 9 Module System Basics
  • Java 9 Module System Examples

5. Process API Improvements


Java SE 9 迎來一些 Process API 的改進(jìn),通過添加一些新的類和方法來優(yōu)化系統(tǒng)級(jí)進(jìn)程的管控。

Process API 中的兩個(gè)新接口:

  • java.lang.ProcessHandle
  • java.lang.ProcessHandle.Info

Process API 示例

ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("Current Process Id: = " + currentProcess.getPid());

想了解更多新 API 的信息,可以通過參考我的初體驗(yàn)之:Java SE 9: Process API Improvements。

6. Try With Resources Improvement


我們知道,Java SE 7 引入了一個(gè)新的異常處理結(jié)構(gòu):Try-With-Resources,來自動(dòng)管理資源。這個(gè)新的聲明結(jié)構(gòu)主要目的是實(shí)現(xiàn)“Automatic Better Resource Management”(“自動(dòng)資源管理”)。

Java SE 9 將對(duì)這個(gè)聲明作出一些改進(jìn)來避免一些冗長(zhǎng)寫法,同時(shí)提高可讀性。

Java SE 7 示例

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}

Java SE 9 示例

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}

有關(guān)這個(gè)特性的更多信息,可以參考我的初體驗(yàn)之:Java 9 Try-With-Resources Improvements

7. CompletableFuture API Improvements


在 Java SE 9 中,Oracle 公司將改進(jìn) CompletableFuture API 來解決一些 Java SE 8 中出現(xiàn)的問題。這些被添加的 API 將用來支持一些延時(shí)和超時(shí)操作,實(shí)用方法和更好的子類化。

Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);

這里的 delayedExecutor() 是靜態(tài)實(shí)用方法,用來返回一個(gè)在指定延時(shí)時(shí)間提交任務(wù)到默認(rèn)執(zhí)行器的新 Executor 對(duì)象。

有關(guān)這個(gè)特性的更多信息,請(qǐng)?jiān)L問我的初體驗(yàn)之:Java SE 9: CompletableFuture API Improvements。

8. Reactive Streams


現(xiàn)在,Reactive Programming 由于其便利性在應(yīng)用程序開發(fā)中變得非常流行。Scala、Play、Akka 等框架已經(jīng)集成 Reactive Streams 并且受益良多。Oracle 公司也在 Java SE 9 中引入了一個(gè)新的 Reactive Streams API。

Java SE 9 Reactive Streams API 是一個(gè)發(fā)布訂閱型框架,使我們能夠非常簡(jiǎn)單地使用 Java 語(yǔ)言就能實(shí)現(xiàn)異步的、可拓展的和并行的應(yīng)用。

Java SE 9 引進(jìn)下面這些 API 來在基于 Java 語(yǔ)言的應(yīng)用中開發(fā) Reactive Streams:

  • java.util.concurrent.Flow
  • java.util.concurrent.Flow.Publisher
  • java.util.concurrent.Flow.Subscriber
  • java.util.concurrent.Flow.Processor

如果你想了解這個(gè)新 API 的更多信息,可以參考我的初體驗(yàn)之:Introduction to Reactive Programming and Java SE 9: Reactive Streams。

9. Diamond Operator for Anonymous Inner Class


我們知道,Java SE 7 引入了一個(gè)新的特性:Diamond Operator,來避免冗長(zhǎng)代碼和提升可讀性。然而在 Java SE 8 中,Oracle 公司發(fā)現(xiàn)在 Diamond 操作器和匿名內(nèi)部類的使用中存在一些局限性,后來修復(fù)了這些問題并準(zhǔn)備將其作為 Java 9 的一部分發(fā)布出去。

public List getEmployee(String empid){
    // Code to get Employee details from Data Store
    return new List(emp){ };
}

10. Optional Class Improvements


在 Java SE 9 中,Oracle 公司添加了一些新的實(shí)用方法到 java.util.Optional 類里面。這里我將使用一些簡(jiǎn)單的示例來描述其中的一個(gè):stream 方法。

如果一個(gè)值出現(xiàn)在給定 Optional 對(duì)象中,stream() 方法可以返回包含該值的一個(gè)順序 Stream 對(duì)象。否則,將返回一個(gè)空 Stream。

stream() 方法已經(jīng)被添加,并用來在 Optional 對(duì)象中使用,如:

Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)

這里的 Optional.stream() 方法被用來轉(zhuǎn)化 Employee 可選流對(duì)象 到 Employee 流中,如此我們便可以在后續(xù)代碼中使用這個(gè)結(jié)果。

理解這個(gè)特性的更多信息,可參考我的初體驗(yàn)過程:Java SE 9: Optional Class Improvements

11. Stream API Improvements


在 Java SE 9 中,Oracle 公司添加了四個(gè)非常有用的新方法到 java.util.Stream 接口里面。正如 Stream 作為一個(gè)接口類,所有這些新的實(shí)現(xiàn)方法都是默認(rèn)方法。其中有兩個(gè)方法非常重要:dropWhile 和 takeWhile。

如果你熟悉 Scala 語(yǔ)言或者其它函數(shù)編程語(yǔ)言的話,你一定知道這些方法。他們?cè)趯懸恍┕δ軜邮酱a時(shí)非常有用。這里我們一起討論一下 takeWhile 實(shí)用方法。

這個(gè) takeWhile() 方法使用一個(gè)斷言作為參數(shù),返回給定 Stream 的子集直到斷言語(yǔ)句第一次返回 false。如果第一個(gè)值不滿足斷言條件,將返回一個(gè)空的 Stream。

jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4

更多有關(guān) takeWhile、dropWhile 和其它新方法的信息,可以參考我的初體驗(yàn)過程之:Java SE 9: Stream API Improvements

12. Enhanced @Deprecated annotation


在 Java SE 8 和更早版本上,@Deprecated 注解只是一個(gè)沒有任何方法的標(biāo)記類接口。它的作用是標(biāo)記一個(gè) Java API,可以是 calss,field,method,interface,constructor 等。

在 Java SE 9 中,Oracle 公司強(qiáng)化了 @Deprecated 注解,來提供更多有關(guān)廢棄 API 的介紹信息,同時(shí)也提供一個(gè)工具來分析項(xiàng)目中的廢棄 API 的靜態(tài)使用情況。Oracle 公司添加了兩個(gè)方法到 Deprecated 接口中來提供服務(wù):forRemovalsince

13. HTTP 2 Client


在 Java SE 9 中,Oracle 公司將發(fā)布新的 HTTP 2 Client API 來支持 HTTP/2 協(xié)議和 WebSocket 特性。現(xiàn)有的 HTTP Client API 存在很多問題(如支持 HTTP/1.1 協(xié)議但是不支持 HTTP/2 協(xié)議和 WebSocket,僅僅作用在 Blocking 模式中,并存在大量性能問題),他們正在被使用新的 HTTP 客戶端的 HttpURLConnection API 所替代。

Oracle 公司準(zhǔn)備在 “java.net.http” 包下引入新的 HTTP 2 Client API。它將同時(shí)支持 HTTP/1.1 和 HTTP/2 協(xié)議,也同時(shí)支持同步(Blocking Mode)和異步模式,支持 WebSocket API 使用中的異步模式。

我們可以在這里查看這個(gè)新 API 信息:http://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html

HTTP 2 Client 示例

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("http://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> http://rams4java.blogspot.co.uk/2016/05/java-news.html

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))

可以通過我的初體驗(yàn)之:Java SE 9: HTTP 2 Client,理解 HTTP/2 協(xié)議和 WebSocket,以及使用一些有用的示例對(duì)比新 API 的優(yōu)勢(shì)和舊 OLD API 的缺陷。

14. Мulti-Resolution Image API


在 Java SE 9 中,Oracle 公司將引入一個(gè)新的 Мulti-Resolution Image API。這個(gè) API 中比較重要的接口是 MultiResolutionImage,在 java.awt.image 包下可獲取到。

MultiResolutionImage 封裝不同高度和寬度圖片(不同解決方案)到一個(gè)集合中,并允許我們按需查詢使用。

想理解這個(gè) API 的更多信息,可參考我的初體驗(yàn)之:Java SE 9: Мulti-Resolution Image API

15. Miscellaneous Java 9 Features


在這個(gè)部分,我將列出 Java SE 9 新特性中其它一些內(nèi)容。當(dāng)然,這并不是這些內(nèi)容就不重要。使用一些示例去理解他們也是非常重要并且很實(shí)用的。

截至目前,我并沒有獲取到這些特性的足夠多信息。這就是為什么我將他們簡(jiǎn)單列舉至此的原因。我也會(huì)一個(gè)一個(gè)去獲取信息并采用一些示例來說明這個(gè)部分列舉的特性內(nèi)容。并且會(huì)在晚些寫成一個(gè)獨(dú)立的體驗(yàn)部分。

  • GC (Garbage Collector) Improvements
  • Stack-Walking API
  • Filter Incoming Serialization Data
  • Deprecate the Applet API
  • Indify String Concatenation
  • Enhanced Method Handles
  • Java Platform Logging API and Service
  • Compact Strings
  • Parser API for Nashorn
  • Javadoc Search
  • HTML5 Javadoc

后面我將逐個(gè)搜集這些 java 9 中的特性,并使用足夠的描述性文字和示例代碼予以解釋。

至此,上述就是 java 9 中所有新引進(jìn)的特性,一些簡(jiǎn)介和示例代碼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容