Java 9 是一个主要版本,它为我们开发人员带来了很多功能。在本文中,我们将详细研究 Java 9 功能。
Java 10 已发布,有关 Java 10 版本的完整概述,请访问Java 10 特性.
Some of the important java 9 features are;
- Java 9 REPL(JShell)
- 不可变列表、集合、映射和 Map.Entry 的工厂方法
- 接口中的私有方法
- Java 9 模块系统
- 流程 API 改进
- 尝试改善资源
- CompletableFuture API 改进
- 反应式流
- 匿名内部类的钻石运算符
- 可选的类改进
- 流 API 改进
- 增强的@Deprecated注释
- HTTP 2 客户端
- 多分辨率图像API
- 其他 Java 9 功能
Oracle 公司将于 2017 年 3 月底左右发布 Java SE 9。在这篇文章中,我将通过一些示例简要讨论“Java 9 功能”。
Oracle 公司推出了一款名为“jshell”的新工具。它代表 Java Shell,也称为 REPL(读取评估打印循环)。它用于非常轻松地执行和测试任何 Java 结构,如类、接口、枚举、对象、语句等。我们可以从以下位置下载 JDK 9 EA(早期访问)软件: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 基础知识(第 1 部分) and Java 9 REPL 功能(第 2 部分).
Oracle 公司引入了一些方便的工厂方法来创建 Immutable List、Set、Map 和 Map.Entry 对象。这些实用方法用于创建空或非空 Collection 对象。在 Java SE 8 及更早版本中,我们可以使用 Collections 类实用方法,例如unmodifiableXXX
创建不可变集合对象。例如,如果我们想创建一个不可变列表,那么我们可以使用Collections.unmodifiableList
方法。然而,这些Collections.unmodifiableXXX
方法是一种乏味且冗长的方法。为了克服这些缺点,Oracle 公司在 List、Set 和 Map 接口中添加了一些实用方法。 List 和 Set 接口具有“of()”方法来创建空或非空的 Immutable List 或 Set 对象,如下所示:空列表示例
List immutableList = List.of();
非空列表示例
List immutableList = List.of("one","two","three");
Map 有两组方法:of()
方法和ofEntries()
分别创建 Immutable Map 对象和 Immutable Map.Entry 对象的方法。空地图示例
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 不可变列表的工厂方法
- Java 9 不可变集的工厂方法
- 用于不可变 Map 和 Map.Entry 的 Java 9 工厂方法
在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 功能的一大变化是模块系统。甲骨文公司将推出以下功能作为拼图项目.
- 模块化JDK
- 模块化 Java 源代码
- 模块化运行时映像
- 封装Java内部API
- Java平台模块系统
在 Java SE 9 版本之前,我们使用 Monolithic Jars 来开发基于 Java 的应用程序。这种架构有很多限制和缺点。为了避免所有这些缺点,Java SE 9 附带了模块系统。 JDK 9 附带 92 个模块(在最终版本中可能会发生变化)。我们可以使用 JDK 模块,也可以创建自己的模块,如下所示:简单模块示例
module com.foo.bar { }
这里我们使用“module”来创建一个简单的模块。每个模块都有名称、相关代码和其他资源。要了解有关此新架构和实践经验的更多详细信息,请在此处浏览我的原始教程:
- Java 9 模块系统基础知识
- 使用命令提示符的 Java 9 模块示例
- 使用 Eclipse IDE 的 Java 9 Hello World 模块示例
Java SE 9 对 Process API 进行了一些改进。他们添加了几个新的类和方法来简化操作系统进程的控制和管理。 Process 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("journaldev.txt"));
try (BufferedReader reader2 = reader1) {
System.out.println(reader2.readLine());
}
}
Java 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 改进
在 Java SE 9 中,Oracle 公司将改进 CompletableFuture API 以解决 Java SE 8 中出现的一些问题。他们将添加支持一些延迟和超时、一些实用方法和更好的子类化。
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
这里delayedExecutor()是一个静态实用方法,用于返回一个新的Executor,该Executor在给定的延迟后将任务提交给默认的executor。
如今,响应式编程在开发应用程序中变得非常流行,并获得了一些好处。 Scala、Play、Akka 等框架已经集成了 Reactive Streams 并获得了很多好处。 Oracle Corps 还在 Java SE 9 中引入了新的 Reactive Streams API。Java SE 9 Reactive Streams 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引入了一项新功能:Diamond Operator,以避免冗余代码和冗长,提高可读性。然而,在 Java SE 8 中,Oracle 公司(Java 库开发人员)发现在匿名内部类中使用 Diamond 运算符存在一些限制。他们已经解决了这些问题并将作为 Java 9 的一部分发布。
public List getEmployee(String empid){
// Code to get Employee details from Data Store
return new List(emp){ };
}
这里我们只使用“List”而不指定类型参数。
在 Java SE 9 中,Oracle 公司向 java.util.Optional 类添加了一些有用的新方法。在这里,我将通过一些简单的示例来讨论其中一种方法:stream 方法 如果给定的Optional对象中存在一个值,则此stream()方法将返回具有该值的顺序Stream。否则,它返回一个空 Stream。他们添加了“stream()”方法来延迟处理可选对象,如下所示:
Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)
这里Optional.stream()方法用于将Employee对象的Optional流转换为Employee流,以便我们可以在结果代码中延迟处理这个结果。要通过更多示例了解有关此功能的更多信息,并阅读添加到Optional类中的更多新方法,请阅读我的原始教程:Java SE 9:可选类改进
在 Java SE 9 中,Oracle 公司向 java.util.Stream 接口添加了四个有用的新方法。由于 Stream 是一个接口,所有这些新实现的方法都是默认方法。其中两个非常重要:dropWhile 和 takeWhile 方法如果您熟悉 Scala 语言或任何 Functions 编程语言,您一定会知道这些方法。这些是编写一些函数式代码时非常有用的方法。让我们在这里讨论 takeWhile 实用方法。该 takeWhile() 将谓词作为参数,并返回给定 Stream 值的子集的 Stream,直到该谓词第一次返回 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
要了解有关 takeWhile 和 dropWhile 方法以及其他新方法的更多信息,请浏览我的原始教程:Java SE 9:流 API 改进
在 Java SE 8 及更早版本中,@已弃用注解只是一个Marker接口,没有任何方法。它用于标记 Java API,即类、字段、方法、接口、构造函数、枚举等。在 Java SE 9 中,Oracle 公司增强了@已弃用注释以提供有关已弃用 API 的更多信息,并提供Tool分析应用程序对已弃用 API 的静态使用情况。他们向这个已弃用的接口添加了两个方法:用于移除 and since来提供此信息。
在 Java SE 9 中,Oracle 公司将发布新的 HTTP 2 客户端 API 以支持 HTTP/2 协议和 WebSocket 功能。由于现有或旧版 HTTP 客户端 API 存在许多问题(例如支持 HTTP/1.1 协议,但不支持 HTTP/2 协议和 WebSocket,仅在阻止模式下工作以及存在许多性能问题。),他们正在用新的 HTTP 替换此 HttpURLConnection API客户。他们将在“java.net.http”包下引入新的 HTTP 2 客户端 API。它支持 HTTP/1.1 和 HTTP/2 协议。它支持同步(阻塞模式)和异步模式。它支持使用 WebSocket API 的异步模式。我们可以在以下位置看到这个新 API:https://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html HTTP 2 客户端示例
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 客户端通过一些有用的示例来了解 HTTP/2 协议和 WebSocket、新 API 的优点和旧 API 的缺点。
在 Java SE 9 中,Oracle 公司将引入新的多分辨率图像 API。此 API 中的重要接口是 MultiResolutionImage 。它在 java.awt.image 包中可用。 MultiResolutionImage 封装了一组具有不同高度和宽度(即不同分辨率)的图像,并允许我们根据需要查询它们。
在本节中,我将仅列出一些 Java SE 9 新功能。我并不是说这些是不太重要的功能。它们对于通过一些有用的示例很好地理解它们也很重要且有用。截至目前,我还没有获得有关这些功能的足够信息。这就是为什么我要在这里列出它们以供简要了解。我将一一挑选这些功能,并通过简短的讨论和示例添加到上面的部分中。最后写一个单独的教程。
- GC(垃圾收集器)改进
- 堆栈遍历 API
- 过滤传入的序列化数据
- 弃用 Applet API
- 指示字符串连接
- 增强的方法句柄
- Java 平台日志记录 API 和服务
- 紧凑弦乐
- Nashorn 的解析器 API
- Javadoc 搜索
- HTML5 Java文档
我将一一拾取这些 java 9 功能,并用足够的描述和示例来更新它们。这就是关于 Java 9 功能的简要介绍和示例。