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

Java 作为 Android 的基础编程语言,每一次迭代也是备受安卓开发人员的关注。这不,Oracle 公司在今年即将发布 Java 9 正式版,一些新的特性和改进很是值得期待。

周末时间,拜读了国外的一个 Java 大牛写的有关 Java SE 9 的新功能介绍,简明扼要,示例得当。于是,一时兴起,以拙劣的英语水平磕磕绊绊翻译至此,供大家了解一番。

作者:「Rambabu Posa」,一个具有 11 年丰富开发经验的技术牛人。

英文出处:Java 9 Features with Examples

Oracle 公司即将在 2017 年 3 月底正式发布 Java SE 9。在这篇文章,我将使用一些示例简明扼要地阐述 Java 9 的新特性。当然,也是时候去了解一下。

1. Java 9 PEPK(JShell)


Oracle 公司(Java Library 开发者)新引进一个代表 Java Shell 的称之为 “jshell” 或者 REPL(Read Evaluate Print Loop)的新工具。该工具可以被用来执行和测试任何 Java 中的结构,如 class,interface,enum,object,statements 等。使用非常简单。

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

有关 REPL 工具的更多信息,可访问 Java 9 REPL Basics (Part-1)Java 9 REPL Features (Part-2).

2. 不可变集合类的工厂方法


Oracle 公司引入一些方便使用的工厂方法,用于创建不可变集合 List,Set,Map 和 Map.Entry 对象。这些高效实用的方法可用来创建空或者非空集合对象。

在 Java SE 8 和更早版本中,我们常用类似 unmodifiableXXX 的集合类方法创建不可变集合对象。举个例子,比如我们想创建一个不可变的 List 对象,可能使用到 Collections.unmodifiableList 方法。

然而,这些 Collections.unmodifiableXXX 方法显得非常冗长乏味。为了克服这些缺陷,Oracle 公司给 List、Set 和 Map 接口分别添加了两个更加实用的方法。

List 和 Set 接口使用 of() 方法创建一个空或者非空的不可变 List 或 Set 对象,如:

空 List 示例

List immutableList = List.of();

非空 List 示例

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

Map 分别有两个方法用于创建不可变 Map 对象和不可变 Map.Entry 对象: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}

更多有关这些实用方法的信息,可以通过这些链接查询:

3. 接口中的私有方法


在 Java 8 中,我们可以在接口中使用默认或者静态方法提供一些实现方式,但是不能创建私有方法。

为了避免冗余代码和提高重用性,Oracle 公司准备在 Java SE 9 接口中引入私有方法。也就是说从 Java SE 9 开始,我们也能够在接口类中使用 ‘private’ 关键字写私有化方法和私有化静态方法。

接口中的私有方法与 class 类中的私有方法在写法上并无差异,如:

public interface Card{

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

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

}

有关接口私有方法新特性的更多信息,可访问我的初体验之:Java 9 Private methods in Interface

4. Java 9 Module System


Java 9 新特性中最大的一个变化就是 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 来开发基于 Java 语言的应用程序。这种体系架构有许多局限性和缺点。为了避免这些缺陷,Java SE 9 迎来了 Module System。

JDK 9 包含有 92 个 modules(当然也可能在最终发布版中有所变化)。我们可以使用 JDK Modules,也能创建我们自己的 modules,如:

简单 Module 示例

module com.foo.bar { }

这里我们使用 module 关键字创建了一个简单的 module。每个 module 都有一个名字,对应代码和其它一些资源。

想了解更多有关这个新体系架构和亲自动手体验的话,可以参考这里我的体验之:

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

5. Process API Improvements


Java SE 9 迎来一些 Process API 的改进,通过添加一些新的类和方法来优化系统级进程的管控。

Process API 中的两个新接口:

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

Process API 示例

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

想了解更多新 API 的信息,可以通过参考我的初体验之:Java SE 9: Process API Improvements。

6. Try With Resources Improvement


我们知道,Java SE 7 引入了一个新的异常处理结构:Try-With-Resources,来自动管理资源。这个新的声明结构主要目的是实现“Automatic Better Resource Management”(“自动资源管理”)。

Java SE 9 将对这个声明作出一些改进来避免一些冗长写法,同时提高可读性。

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

有关这个特性的更多信息,可以参考我的初体验之:Java 9 Try-With-Resources Improvements

7. CompletableFuture API Improvements


在 Java SE 9 中,Oracle 公司将改进 CompletableFuture API 来解决一些 Java SE 8 中出现的问题。这些被添加的 API 将用来支持一些延时和超时操作,实用方法和更好的子类化。

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

这里的 delayedExecutor() 是静态实用方法,用来返回一个在指定延时时间提交任务到默认执行器的新 Executor 对象。

有关这个特性的更多信息,请访问我的初体验之:Java SE 9: CompletableFuture API Improvements。

8. Reactive Streams


现在,Reactive Programming 由于其便利性在应用程序开发中变得非常流行。Scala、Play、Akka 等框架已经集成 Reactive Streams 并且受益良多。Oracle 公司也在 Java SE 9 中引入了一个新的 Reactive Streams API。

Java SE 9 Reactive Streams API 是一个发布订阅型框架,使我们能够非常简单地使用 Java 语言就能实现异步的、可拓展的和并行的应用。

Java SE 9 引进下面这些 API 来在基于 Java 语言的应用中开发 Reactive Streams:

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

如果你想了解这个新 API 的更多信息,可以参考我的初体验之:Introduction to Reactive Programming and Java SE 9: Reactive Streams。

9. Diamond Operator for Anonymous Inner Class


我们知道,Java SE 7 引入了一个新的特性:Diamond Operator,来避免冗长代码和提升可读性。然而在 Java SE 8 中,Oracle 公司发现在 Diamond 操作器和匿名内部类的使用中存在一些局限性,后来修复了这些问题并准备将其作为 Java 9 的一部分发布出去。

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 公司添加了一些新的实用方法到 java.util.Optional 类里面。这里我将使用一些简单的示例来描述其中的一个:stream 方法。

如果一个值出现在给定 Optional 对象中,stream() 方法可以返回包含该值的一个顺序 Stream 对象。否则,将返回一个空 Stream。

stream() 方法已经被添加,并用来在 Optional 对象中使用,如:

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

这里的 Optional.stream() 方法被用来转化 Employee 可选流对象 到 Employee 流中,如此我们便可以在后续代码中使用这个结果。

理解这个特性的更多信息,可参考我的初体验过程:Java SE 9: Optional Class Improvements

11. Stream API Improvements


在 Java SE 9 中,Oracle 公司添加了四个非常有用的新方法到 java.util.Stream 接口里面。正如 Stream 作为一个接口类,所有这些新的实现方法都是默认方法。其中有两个方法非常重要:dropWhile 和 takeWhile。

如果你熟悉 Scala 语言或者其它函数编程语言的话,你一定知道这些方法。他们在写一些功能样式代码时非常有用。这里我们一起讨论一下 takeWhile 实用方法。

这个 takeWhile() 方法使用一个断言作为参数,返回给定 Stream 的子集直到断言语句第一次返回 false。如果第一个值不满足断言条件,将返回一个空的 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

更多有关 takeWhile、dropWhile 和其它新方法的信息,可以参考我的初体验过程之:Java SE 9: Stream API Improvements

12. Enhanced @Deprecated annotation


在 Java SE 8 和更早版本上,@Deprecated 注解只是一个没有任何方法的标记类接口。它的作用是标记一个 Java API,可以是 calss,field,method,interface,constructor 等。

在 Java SE 9 中,Oracle 公司强化了 @Deprecated 注解,来提供更多有关废弃 API 的介绍信息,同时也提供一个工具来分析项目中的废弃 API 的静态使用情况。Oracle 公司添加了两个方法到 Deprecated 接口中来提供服务:forRemovalsince

13. HTTP 2 Client


在 Java SE 9 中,Oracle 公司将发布新的 HTTP 2 Client API 来支持 HTTP/2 协议和 WebSocket 特性。现有的 HTTP Client API 存在很多问题(如支持 HTTP/1.1 协议但是不支持 HTTP/2 协议和 WebSocket,仅仅作用在 Blocking 模式中,并存在大量性能问题),他们正在被使用新的 HTTP 客户端的 HttpURLConnection API 所替代。

Oracle 公司准备在 “java.net.http” 包下引入新的 HTTP 2 Client API。它将同时支持 HTTP/1.1 和 HTTP/2 协议,也同时支持同步(Blocking Mode)和异步模式,支持 WebSocket API 使用中的异步模式。

我们可以在这里查看这个新 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()))

可以通过我的初体验之:Java SE 9: HTTP 2 Client,理解 HTTP/2 协议和 WebSocket,以及使用一些有用的示例对比新 API 的优势和旧 OLD API 的缺陷。

14. Мulti-Resolution Image API


在 Java SE 9 中,Oracle 公司将引入一个新的 Мulti-Resolution Image API。这个 API 中比较重要的接口是 MultiResolutionImage,在 java.awt.image 包下可获取到。

MultiResolutionImage 封装不同高度和宽度图片(不同解决方案)到一个集合中,并允许我们按需查询使用。

想理解这个 API 的更多信息,可参考我的初体验之:Java SE 9: Мulti-Resolution Image API

15. Miscellaneous Java 9 Features


在这个部分,我将列出 Java SE 9 新特性中其它一些内容。当然,这并不是这些内容就不重要。使用一些示例去理解他们也是非常重要并且很实用的。

截至目前,我并没有获取到这些特性的足够多信息。这就是为什么我将他们简单列举至此的原因。我也会一个一个去获取信息并采用一些示例来说明这个部分列举的特性内容。并且会在晚些写成一个独立的体验部分。

  • 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

后面我将逐个搜集这些 java 9 中的特性,并使用足够的描述性文字和示例代码予以解释。

至此,上述就是 java 9 中所有新引进的特性,一些简介和示例代码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容