Java 9 新特性概览

Java 9 发布于 2017 年 9 月 21 日 。作为 Java 8 之后 3 年半才发布的新版本,Java 9 带来了很多重大的变化其中最重要的改动是 Java 平台模块系统的引入,其他还有诸如集合、Stream 流......。

JEP 222: jshell-Java 命令行工具

JShell 是 Java 9 新增的一个实用工具。为 Java 提供了类似于 Python 的实时命令行交互工具。

在 JShell 中可以直接输入表达式并查看其执行结果。

Java 9 新特性概览_第1张图片

JShell 为我们带来了哪些好处呢?

降低了输出第一行 Java 版"Hello World!"的门槛,能够提高新手的学习热情。
在处理简单的小逻辑,验证简单的小问题时,比 IDE 更有效率(并不是为了取代 IDE,对于复杂逻辑的验证,IDE 更合适,两者互补)。

JShell 的代码和普通的可编译代码,有什么不一样?

一旦语句输入完成,JShell 立即就能返回执行的结果,而不再需要编辑器、编译器、解释器。
JShell 支持变量的重复声明,后面声明的会覆盖前面声明的。
JShell 支持独立的表达式比如普通的加法运算 1 + 1。

JEP 261: 模块化系统

什么是模块系统? 官方的定义是:

A uniquely named, reusable group of related packages, as well as resources (such as images and XML files) and a module descriptor。

简单来说,你可以将一个模块看作是一组唯一命名、可重用的包、资源和模块描述文件(module-info.java)。

把模块化开发实践引入到了 Java 平台中,可以让我们的代码可重用性更好!

任意一个 jar 文件,只要加上一个模块描述文件(module-info.java),就可以升级为一个模块。

Java 9 新特性概览_第2张图片

在引入了模块系统之后,JDK 被重新组织成 94 个模块。Java 应用可以通过新增的 jlinkopen in new window 工具 (Jlink 是随 Java 9 一起发布的新命令行工具。它允许开发人员为基于模块的 Java 应用程序创建自己的轻量级、定制的 JRE),创建出只包含所依赖的 JDK 模块的自定义运行时镜像。这样可以极大的减少 Java 运行时环境的大小。

我们可以通过 exports 关键词精准控制哪些类可以对外开放使用,哪些类只能内部使用。

JEP 248:G1 成为默认垃圾回收器

在 Java 8 的时候,默认垃圾回收器是 Parallel Scavenge(新生代)+Parallel Old(老年代)。到了 Java 9, CMS 垃圾回收器被废弃了,G1(Garbage-First Garbage Collector) 成为了默认垃圾回收器。

G1 还是在 Java 7 中被引入的,经过两个版本优异的表现成为成为默认垃圾回收器。

JEP 193: 变量句柄

变量句柄是一个变量或一组变量的引用,包括静态域,非静态域,数组元素和堆外数据结构中的组成部分等。

变量句柄的含义类似于已有的方法句柄 MethodHandle ,由 Java 类 java.lang.invoke.VarHandle 来表示,可以使用类 java.lang.invoke.MethodHandles.Lookup 中的静态工厂方法来创建 VarHandle 对象。

VarHandle 的出现替代了 java.util.concurrent.atomic 和 sun.misc.Unsafe 的部分操作。并且提供了一系列标准的内存屏障操作,用于更加细粒度的控制内存排序。在安全性、可用性、性能上都要优于现有的 API。

JEP 110: HTTP 2 Client

JEP 143: 优化竞争锁的性能

JEP 197: 分段代码缓存

JEP 199: 智能java编译工具

200: The Modular JDK

201: Modular Source Code

JEP 254:字符串存储结构优化

Java 8 及之前的版本,String 一直是用 char[] 存储。在 Java 9 之后,String 的实现改用 byte[] 数组存储字符串,节省了空间。

接口私有方法

Java 9 允许在接口中使用私有方法。这样的话,接口的使用就更加灵活了,有点像是一个简化版的抽象类。

try-with-resources 增强

在 Java 9 之前,我们只能在 try-with-resources 块中声明变量:

在 Java 9 之后,在 try-with-resources 语句中可以使用 effectively-final 变量。

final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) {
    // omitted
}

什么是 effectively-final 变量?
简单来说就是没有被 final 修饰但是值在初始化后从未更改的变量。正如上面的代码所演示的那样,即使 writer 变量没有被显示声明为 final,但它在第一次被复制后就不会改变了,因此,它就是 effectively-final 变量。

Stream & Optional 增强

Stream 中增加了新的方法 ofNullable()、dropWhile()、takeWhile() 以及 iterate() 方法的重载方法。

Java 9 中的 ofNullable() 方 法允许我们创建一个单元素的 Stream,可以包含一个非空元素,也可以创建一个空 Stream。 而在 Java 8 中则不可以创建空的 Stream 。

进程 API

Java 9 增加了 java.lang.ProcessHandle 接口来实现对原生进程进行管理,尤其适合于管理长时间运行的进程。

// 获取当前正在运行的 JVM 的进程
ProcessHandle currentProcess = ProcessHandle.current();
// 输出进程的 id
System.out.println(currentProcess.pid());
// 输出进程的信息
System.out.println(currentProcess.info());

响应式流 ( Reactive Streams )

在 Java 9 中的 java.util.concurrent.Flow 类中新增了反应式流规范的核心接口 。

Flow 中包含了 Flow.Publisher、Flow.Subscriber、Flow.Subscription 和 Flow.Processor 等 4 个核心接口。Java 9 还提供了SubmissionPublisher 作为Flow.Publisher 的一个实现。

快速创建不可变集合

增加了List.of()、Set.of()、Map.of() 和 Map.ofEntries()等工厂方法来创建不可变集合(有点参考 Guava 的味道):

List.of("Java", "C++");
Set.of("Java", "C++");
Map.of("Java", 1, "C++", 2);

使用 of() 创建的集合为不可变集合,不能进行添加、删除、替换、 排序等操作,不然会报 java.lang.UnsupportedOperationException 异常。

你可能感兴趣的:(java9)