Java 9 是一个重要的版本,为开发者带来了许多新特性。在这篇文章中,我们将详细介绍 Java 9 的特性。
Java 10 已经发布,要了解 Java 10 发布的完整概述,请查看 Java 10 特性。
Java 9 特性
- Java 9 REPL(JShell)
- 不可变列表、集合、映射和映射条目的工厂方法
- 接口中的私有方法
- Java 9 模块系统
- 进程 API 改进
- 改进的资源管理
- CompletableFuture API 改进
- 响应式流
- 匿名内部类的钻石操作符
- Optional 类改进
- 流 API 改进
- 增强的 @Deprecated 注解
- HTTP 2 客户端
- 多分辨率图像 API
- 杂项 Java 9 特性
Oracle 公司计划在 2017 年 3 月底左右发布 Java SE 9。在本文中,我将简要讨论一些“Java 9 特性”,并附带一些示例。
Java 9 REPL (JShell)
Oracle 公司推出了一个名为“jshell”的新工具。它代表 Java Shell,也被称为 REPL(Read Evaluate Print Loop)。它用于非常轻松地执行和测试任何 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 基础知识(第一部分) 和 Java 9 REPL 特性(第二部分)。
Immutable List、Set、Map 和 Map.Entry 的工厂方法
Oracle 公司推出了一些方便的工厂方法,用于创建不可变的 List、Set、Map 和 Map.Entry 对象。这些实用方法用于创建空的或非空的集合对象。在 Java SE 8 及之前的版本中,我们可以使用 Collections 类的实用方法,比如 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 有两组方法:of()
方法和 ofEntries()
方法,分别用于创建不可变的 Map 对象和不可变的 Map.Entry 对象。空 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}
如果您想了解更多关于这些实用方法的信息,请参阅以下链接:
接口中的私有方法
在Java 8中,我们可以使用默认方法和静态方法在接口中提供方法实现。然而,我们无法在接口中创建私有方法。为了避免冗余代码并提高可重用性,Oracle公司将在Java SE 9接口中引入私有方法。从Java SE 9开始,我们可以使用’private’关键字在接口中编写私有和私有静态方法。这些私有方法与其他类的私有方法一样,它们之间没有区别。
public interface Card{
private Long createCardID(){
// 方法实现在这里。
}
private static void displayCardDetails(){
// 方法实现在这里。
}
}
如果您想了解更多关于这一新功能的信息,请阅读此链接:Java 9 接口中的私有方法。
Java 9 模块系统
Java 9 的一个重大变化或特性是模块系统。Oracle公司将引入以下特性作为拼图项目的一部分。
- 模块化JDK
- 模块化Java源代码
- 模块化运行时镜像
- 封装Java内部APIs
- Java平台模块系统
在Java SE 9版本之前,我们使用单体Jars来开发基于Java的应用程序。这种架构有很多限制和缺点。为了避免所有这些缺点,Java SE 9带来了模块系统。JDK 9带来了92个模块(在最终发布中可能会有变化)。我们可以使用JDK模块,也可以像下面显示的那样创建我们自己的模块:简单模块示例
module com.foo.bar { }
这里我们使用‘module’来创建一个简单的模块。每个模块都有一个名称、相关代码和其他资源。要了解更多关于这种新架构的详细信息和实践经验,请阅读我这里的原始教程:
进程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());
Try With Resources改进
我们知道,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改进
CompletableFuture API改进
在Java SE 9中,Oracle Corp将改进CompletableFuture API以解决Java SE 8中提出的一些问题。他们将添加对一些延迟和超时的支持,一些实用方法和更好的子类化。
Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
这里的delayedExecutor()是一个静态实用方法,用于在给定的延迟之后将任务提交给默认执行程序。
响应式流
如今,响应式编程在开发应用程序中变得非常流行,以获得一些美好的优势。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的应用程序中开发Reactive Streams。
- java.util.concurrent.Flow
- java.util.concurrent.Flow.Publisher
- java.util.concurrent.Flow.Subscriber
- java.util.concurrent.Flow.Processor
阅读更多关于Java 9 Reactive Streams。
匿名内部类的钻石操作符
我们知道,Java SE 7引入了一个新特性:钻石操作符,以避免冗余代码和冗长,提高可读性。然而,在Java SE 8中,Oracle公司(Java库开发者)发现了在使用匿名内部类时钻石操作符存在一些限制。他们已经修复了这些问题,并打算将它们作为Java 9的一部分发布。
public List getEmployee(String empid){
// 从数据存储中获取员工详细信息的代码
return new List(emp){ };
}
这里我们只使用了“List”而没有指定类型参数。
Optional类的改进
在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
Stream API 改进
在Java SE 9中,Oracle Corp已向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改进
增强@Deprecated注释
在Java SE 8及之前的版本中,@Deprecated注解只是一个没有任何方法的标记接口。它用于标记Java API,即类、字段、方法、接口、构造函数、枚举等。在Java SE 9中,Oracle Corp已经增强了@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客户端替换这个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。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("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(垃圾收集器)改进
- Stack-Walking API
- 过滤传入序列化数据
- 弃用Applet API
- 字符串拼接优化
- 增强的方法句柄
- Java平台日志记录API和服务
- 紧凑字符串
- Nashorn解析器API
- Javadoc搜索
- HTML5 Javadoc
I will pickup these java 9 features one by one and update them with enough description and examples. That’s all about Java 9 features in brief with examples.
Source:
https://www.digitalocean.com/community/tutorials/java-9-features-with-examples