Java 9 特性举例
Java 9是一个重要的版本发布,为开发者带来了许多功能。在这篇文章中,我们将详细介绍Java 9的特性。
Java 10已经发布,想了解Java 10发布的完整概述,请阅读Java 10功能。
Java 9的特性
一些重要的Java 9功能包括:
-
- Java 9中的REPL(JShell)
-
- 不可变列表、集合、映射和映射条目的工厂方法
-
- 接口中的私有方法
-
- Java 9模块系统
-
- 进程API改进
-
- 资源处理改进
-
- CompletableFuture API改进
-
- 响应式流
-
- 匿名内部类的钻石操作符
-
- Optional类改进
-
- 流API改进
-
- 增强的@Deprecated注释
-
- HTTP 2客户端
-
- 多分辨率图像API
- 其他Java 9功能
甲骨文公司计划于2017年3月底发布Java SE 9。在这篇文章中,我将简要讨论一些“Java 9特性”,并给出一些示例。
Java 9 REPL(JShell)是什么?
Oracle公司推出了一个名为“jshell”的新工具。它代表Java Shell,也被称为REPL(读取评估打印循环)。它非常容易地用于执行和测试任何Java构造,如类,接口,枚举,对象,语句等。我们可以从https://jdk9.java.net/download/下载JDK 9 EA(早期访问)软件。
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 基础知识(第1部分)》和《Java 9 REPL 特性(第2部分)》。
不可变列表、集合、映射和映射项的工厂方法
Oracle公司引入了一些便利的工厂方法,用于创建不可变的List、Set、Map和Map.Entry对象。这些实用方法用于创建空的或非空的Collection对象。在Java SE 8和之前的版本中,我们可以使用Collections类的实用方法,如unmodifiableXXX来创建不可变的Collection对象。例如,如果我们想创建一个不可变的List,则可以使用Collections.unmodifiableList方法。然而,这些Collections.unmodifiableXXX方法是一种繁琐而冗长的方法。为了克服这些缺点,Oracle公司在List、Set和Map接口中添加了几个实用方法。List和Set接口有“of()”方法,用于创建空的或非空的不可变的List或Set对象,如下所示:空List的示例
List immutableList = List.of();
非空列表示例
List immutableList = List.of("one","two","three");
地图有两套方法:of()方法和ofEntries()方法分别用于创建不可变的地图对象和不可变的地图条目对象。空地图示例。
jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}
非空地图示例
jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}
如果您想阅读更多关于这些实用方法的内容,请阅读以下链接:
- Java 9 Factory Methods for Immutable List
- Java 9 Factory Methods for Immutable Set
- Java 9 Factory Methods for Immutable Map and Map.Entry
接口中的私有方法
在Java 8中,我们可以使用默认和静态方法在接口中提供方法实现。然而,我们不能在接口中创建私有方法。为了避免冗余代码并增加可重用性,Oracle公司将在Java SE 9接口中引入私有方法。从Java SE 9开始,我们可以使用“private”关键字在接口中编写私有方法和私有静态方法。这些私有方法和其他类的私有方法一样,没有任何区别。
public interface Card{
private Long createCardID(){
// Method implementation goes here.
}
private static void displayCardDetails(){
// Method implementation goes here.
}
}
如果你想要阅读更多关于这个新功能的内容,请通过这个链接查看:Java 9接口中的私有方法。
Java 9 的模块系统
Jigsaw 项目的一项重大变革或 Java 9 功能是模块系统。Oracle 公司将作为 Jigsaw 项目的一部分推出以下特性。
- Modular JDK
- Modular Java Source Code
- Modular Run-time Images
- Encapsulate Java Internal APIs
- Java Platform Module System
在Java SE 9之前的版本中,我们使用单体Jars来开发基于Java的应用程序。这种架构有很多限制和缺点。为了避免所有这些问题,Java SE 9引入了模块化系统。JDK 9带有92个模块(最终发布可能会有所变化)。我们可以使用JDK模块,也可以按以下示例创建我们自己的模块:简单模块示例。
module com.foo.bar { }
在这里,我们正在使用“模块”来创建一个简单的模块。每个模块都有一个名称,相关的代码和其他资源。要了解更多关于这种新架构的详细信息和实际操作经验,请查阅我在这里的原创教程。
- Java 9 Module System Basics
- Java 9 Module Examples using command prompt
- Java 9 Hello World Module Example using Eclipse IDE
过程API改进
Java SE 9将带来一些进程API的改进。他们增加了几个新的类和方法来方便控制和管理操作系统进程。进程API中的两个新接口:
- java.lang.ProcessHandle
- java.lang.ProcessHandle.Info
API示例的处理过程
ProcessHandle currentProcess = ProcessHandle.current();
System.out.println("Current Process Id: = " + currentProcess.getPid());
改进了“尝试使用资源”的功能。
我们知道,Java SE 7引入了一种新的异常处理构造:Try-With-Resources,用于自动管理资源。这个新语句的主要目标是“自动更好的资源管理”。Java SE 9将为这个语句提供一些改进,以避免一些冗长,并提高一些可读性。Java SE 7的例子。
void testARM_Before_Java9() throws IOException{
BufferedReader reader1 = new BufferedReader(new FileReader("scdev.txt"));
try (BufferedReader reader2 = reader1) {
System.out.println(reader2.readLine());
}
}
Java 9 示例
void testARM_Java9() throws IOException{
BufferedReader reader1 = new BufferedReader(new FileReader("scdev.txt"));
try (reader1) {
System.out.println(reader1.readLine());
}
}
要了解关于这个新功能的更多信息,请阅读我原始教程中的内容:Java 9 Try-With-Resources 改进。
CompletableFuture API的改进
在Java SE 9中,甲骨文公司将改进CompletableFuture API以解决Java SE 8中提出的一些问题。他们将增加对延迟和超时的支持,一些实用工具方法和更好的子类化。
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
这里的delayedExecutor()是一个静态实用方法,用于返回一个新的Executor,它会在给定延迟后将任务提交给默认的执行器。
响应式流
如今,响应式编程在开发应用程序中变得非常流行,可以获得一些美好的益处。Scala、Play、Akka等框架已经集成了响应式流并获得了许多好处。Oracle也正在Java SE 9中引入新的响应式流API。Java SE 9的响应式流API是一个发布/订阅框架,可以在Java语言中轻松地实现异步、可扩展和并行应用程序。Java SE 9引入了以下API来开发基于Java的响应式流应用程序。
- java.util.concurrent.Flow
- java.util.concurrent.Flow.Publisher
- java.util.concurrent.Flow.Subscriber
- java.util.concurrent.Flow.Processor
在Java 9的“响应式流”中阅读更多信息。
匿名内部类的钻石操作符
我们知道,Java SE 7引入了一个新的功能:钻石操作符,用于避免冗余代码和啰嗦,改善可读性。然而,在Java SE 8中,Oracle公司(Java库开发人员)发现在使用钻石操作符与匿名内部类时存在一些限制。他们已经修复了这些问题,并计划将其作为Java 9的一部分发布。
public List getEmployee(String empid){
// Code to get Employee details from Data Store
return new List(emp){ };
}
我们在这里使用了“列表”,而没有指定类型参数。
可选的课程改进方案
在Java SE 9中,Oracle公司向java.util.Optional类添加了一些有用的新方法。下面我将讨论其中一个方法,并提供一个简单的示例:stream方法。如果给定的Optional对象中存在一个值,该stream()方法将返回一个顺序流,并包含该值。否则,它将返回一个空的流。如下所示,他们添加了“stream()”方法以懒惰地处理Optional对象。
Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)
在这里,使用Optional.stream()方法将Optional的Employee对象流转换为Employee流,以便我们可以在结果代码中对其进行延迟处理。要了解更多关于这个功能的内容以及Optional类中添加的更多新方法的例子,请阅读我原创的教程:Java SE 9:Optional类的改进。
流API的改进
在Java SE 9中,Oracle Corp已经向java.util.Stream接口中添加了四个有用的新方法。由于Stream是一个接口,所有这些新的实现方法都是默认方法。其中两个非常重要:dropWhile和takeWhile方法。如果您熟悉Scala语言或任何函数式编程语言,您肯定会了解这些方法。这些方法在编写一些函数式风格的代码时非常有用。让我们在这里讨论一下takeWhile实用方法。takeWhile()接受一个谓词作为参数,并返回给定流值的子集流,直到该谓词第一次返回false为止。如果第一个值不满足该谓词,它将返回一个空的流。
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
请阅读我原创的教程《Java SE 9: Stream API改进》,了解更多关于takeWhile和dropWhile方法以及其他新方法的内容。
增强的@Deprecated注解
在Java SE 8以及更早的版本中,@Deprecated注解只是一个没有任何方法的标记接口。它用于标记一个Java API,可以是类、字段、方法、接口、构造函数、枚举等。在Java SE 9中,Oracle公司增强了@Deprecated注解,提供了有关已过时API的更多信息,并提供了一种工具来分析应用程序对已过时API的静态使用情况。他们向这个Deprecated接口添加了两个方法:forRemoval和since,以提供此信息。
HTTP 2 客户端
在Java SE 9中,Oracle Corp将发布新的HTTP 2 Client API,以支持HTTP/2协议和WebSocket功能。由于现有的或传统的HTTP Client API存在许多问题(例如,支持HTTP/1.1协议,不支持HTTP/2协议和WebSocket,仅以阻塞模式工作且性能问题很多),他们打算用新的HTTP Client替换这个HttpURLConnection API。他们将在“java.net.http”包下引入一个新的HTTP 2 Client API。它支持HTTP/1.1和HTTP/2协议。它可以支持同步(阻塞模式)和异步模式。它使用WebSocket API支持异步模式。我们可以在https://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html上看到这个新的API。
jshell> import java.net.http.*
jshell> import static java.net.http.HttpRequest.*
jshell> import static java.net.http.HttpResponse.*
jshell> URI uri = new URI("https://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> https://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的优势以及旧API的缺点,并提供一些有用的例子。
多分辨率图像 API
在Java SE 9中,Oracle Corp将引入一个新的多分辨率图像API。这个API中的重要接口是MultiResolutionImage。它可在java.awt.image包中找到。MultiResolutionImage封装了一组具有不同高度和宽度(即不同分辨率)的图像,并允许我们根据需求进行查询。
Java 9的其他功能
在这个部分,我只会列出一些杂项的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 特性的简要介绍,带有示例。