Java 9 新特性概述

Java9正式发布于2017年9月21日,作为Java8之后3年半才发布的新版本,Java9带来了很多重大的变化,其中最重要的改动是Java模块化的引入。

本文对Java9中包含的新特性做了概括性的介绍,可以帮助你快速了解Java9。

1. 模块化概述

1.1 什么是模块化

模块化(modularization)是指将系统分解成独立且相互连接的模块的行为。模块化不仅仅是一个实现问题(该问题可通过引入新的语言特性来缓解),也是一个设计和架构的问题。应用模块化设计是一项长期的投资。通过模块化,可以应对需求、环境、团队以及其他不可预见事件所带来的变化。

模块(module)是包含代码的可识别工件,使用了元数据来描述模块及其与其他模块的关系。在理想情况下,这些工件从编译时到运行时都是可识别的。一个应用程序由多个模块协作组成。模块必须遵循以下三个核心原则:

1. 强封装性

一个模块必须能够对其他模块隐藏其部分代码。这样一来,就可以在可公开使用的代码和被视为内部实现细节的代码之间划定一条清晰的界限,从而防止模块之间发生意外或不必要的耦合,即无法使用被封装的内容。

2. 定义良好的接口

没有封装的代码是模块公共API的一部分。由于其他模块可以使用这些公共代码,因此必须非常小心地管理它们。未封装代码中任何一个重大更改都可能会破坏依赖该代码的其他模块。

3. 显式依赖

显式依赖会产生一个模块图:节点表示模块,而边缘表示模块之间的依赖关系。拥有模块图对于了解应用程序以及运行所有必要的模块是非常重要的,它为模块的可靠配置提供了基础。

1.2 在Java9之前状况

Java平台在Java9之前的模块化程度确实不尽如人意,下面针对模块化的三个重要特性进行具体分析:

1 强封装性

在Java9之前,通过组合使用包(package)和访问修饰符(比如private、protected或public),可以实现类型封装。但对于public类,无法再限制其它类的访问。

2 定义良好的接口

在定义良好接口方面,Java自诞生以来就一直做得很好,即Java中的interface关键字。

3 显式依赖

Java确实使用了显式的import语句。但从严格意义上讲,这些导入是编译时结构,一旦将代码打包到JAR中,就无法确定哪些JAR包含当前JAR运行所需的类型。

事实上,这个问题非常糟糕,许多外部工具与Java语言一起发展以解决这个问题:Maven和OSGi。

使用Maven构建工具所解决的一个问题是实现编译时依赖关系管理。Maven真正成功之处在于生成了一个名为MavenCentral的规范存储库。

Maven在编译时做了什么,OSGi在运行时就会做什么。它解决了运行时的依赖关系管理。

这两个工具的处理维度都在JAR这一层,一个jar内如果再细分,它们就无能为力了。

4 类路径地狱(classpath hell)

如果在类路径中没有找到所需的类时,会得到一个运行时异常。由于类可以延迟加载,因此只有首次运行应用程序并点击一个按钮时时,才会出现找不到类的情况。

而当类路径上有重复类时,则会出现更为隐蔽的问题。该类的任一版本都可能会被首先加载,此时就会导致运行时异常。一般来说,当类路径包含两个具有相同名称的类时,即使它们完全不相关,也只有一个会被加载。

2. Java9的模块化

Java9之后,强封装性、定义良好的接口以及显式依赖已经成为Java平台的一部分。Java平台模块系统带来了如下最重要的好处:

  • 可靠的配置
  • 强封装
  • 可扩展开发
  • 安全性

JDK9模块化后,由如下这些平台模块组成,不再是一个整体库。

java.se.ee-graph

上图中的模块都是JavaSE规范的一部分,它们的模块名都是以java.*作为前缀。

通过运行 java –list-modules,可以获取平台模块的完整列表。

将JDK分解成模块需要完成大量的工作。将一个错综复杂、有机发展且包含数以万计类的代码库分解成边界清晰且保持向后兼容性的定义良好的模块需要花费大量的时间,这也就是为什么花了如此长的时间才将模块系统植入到Java中的原因。

展望未来,这一努力将在JDK的快速发展以及更大灵活性方面得到丰厚的回报。

3. Java9的其它特性列表

名称 说明
增加Jshell命令 jshell为Java增加了类似 NodeJS 和 Python 中的读取-求值-打印循环( Read-Evaluation-Print Loop )。
集合、Stream 和 Optional 增加了新的方法,List.of()、Set.of()、Map.of() 和 M ap.ofEntries()等工厂方法。
新增ProcessHandle进程管理 可以对原生进程进行管理,尤其适合于管理长时间运行的进程。
改进日志API JDK和应用支持配置同样的日志实现,即JDK内部的日志实现也支持配置了。
集成Reactive Streams 反应式流规范(Reactive Streams)的核心接口已经添加到了 Java9 中的java.util.concurrent.Flow 类中。
新增VarHandle变量句柄 可以对变量进行读取、写入、原子更新、数值原子更新和比特位原子操作等操作,与MethodHandle类似。
改进MethodHandle方法句柄 增加了更多的静态方法来创建不同类型的方法句柄。
改进CompletableFuture CompletableFuture 中增加了几个新的方法。
升级Nashorn 已经实现了一些 ECMAScript 6 规范中的新特性,包括模板字符串、二进制和八进制字面量、迭代器 和 for..of 循环和箭头函数等。
改进I/O API InputStream增加了更加易用的方法。ObjectInputFilter 可以对 ObjectInputStream 中 包含的内容进行检查,来确保其中包含的数据是合法的。
增加哈希算法 新增了4个SHA- 3哈希算法,SHA3-224、SHA3-256、SHA3-384 和 S HA3-512。另外也增加了通过 java.security.SecureRandom 生成使用 DRBG 算法的强随机数。
统一JVM日志 JVM有了统一的日志记录系统,可以使用新的命令行选项-Xlog来控制JVM上所有组件的日志记录。

4. 小结

Java9作为一次重大更新,其中的模块系统无疑是对Java影响最大的,它将影响设计、编译、打包、部署等过程。

本文简单列举了Java9的新特性,使读者对Java9有一个大致印象,以便在开发过程中可以及时联想到这些特性,如果想要查看更详细的内容,可以查阅官方文档。

参考的文章

Java 9 新特性概述
Java 9的模块化–壮士断”腕”的涅槃
Java 9模块化开发:核心原则与实践 (O’Reilly精品图书系列)


文章作者: 沉迷思考的鱼
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 沉迷思考的鱼 !
评论
 上一篇
Java模块系统介绍 Java模块系统介绍
上篇文章介绍了什么是模块化,以及Java模块化解决的问题。本文将介绍Java模块化的相关概念及具体写法。本文将从如下两个方面介绍模块化: 模块描述符 服务 1. 模块描述符为了体现模块之间的关系,必须定义全新的模块描述文件,类似于Ma
2019-10-16
下一篇 
Project Reactor介绍 Project Reactor介绍
上一篇文章中,我们介绍了Reactive Streams规范,现在学习一个Reactive Streams规范的流行实现:Project Reactor的核心项目Reactor Core。 1. Project Reactor 简介Pro
2019-08-02
  目录