JAVA9新特性(二)

JAVA9新特性(二)

JLink

JLink是用来组装和优化模块以及模块依赖项成为一组自定义运行镜像的工具。可以创建针对应用程序进行优化的最小运行时映像而不需要使用完全加载 JDK 安装版本。
JAVA9新特性(二)
JAVA9新特性(二)

Java版本更新字符串格式

版本字符串的格式 $MAJOR.$MINOR.$SECURITY.$PATCH。以后将半年发一版,未完成的任务将不再等候,直接等到下一版本发布。
JAVA9新特性(二)

JShell :THE Java Shell(Read-Eval-Print Lopp)

JAVA9新特性(二)
Java开发者可以利用JShell(jdk中bin目录下)在没有创建类的情况下直接声明变量,计算表达式,执行语句。JShell也可以从文件中加载语句或者将语句保存到文件中。并且JShell也可以是tab键进行自动补全的特性。

代码分段缓存

Java 9的另一个性能提升来自于JIT(Just-in-time)编译器. 当某段代码被大量重复执行的时候, 虚拟机会把这段代码编译成机器码(native code)并储存在代码缓存里面, 进而通过访问缓存中不同分段的代码来提升编译器的效率.
和原来的单一缓存区域不同的是, 新的代码缓存根据代码自身的生命周期而分为三种:
- 永驻代码(JVM 内置 / 非方法代码)
- 短期代码(仅在某些条件下适用的配置性(profiled)代码)
- 长期代码(非配置性代码)
缓存分段会在各个方面提升程序的性能, 比如做垃圾回收扫描的时候可以直接跳过非方法代码(永驻代码), 从而提升效率.

集合工厂方法

Java 9引入了一些有用的工厂方法来创建不可修改的集合。我们现在在Java 9中创建不可修改的Map集合,如下所示。
JAVA9新特性(二)
JAVA9新特性(二)

接口中私有方法

默认方法和静态方法可以共享接口中的私有方法,因此避免了代码冗余,这也使代码更加清晰。
JAVA9新特性(二)

改进的JAVADOC

Javadoc 现在支持在 API 文档中的进行搜索。另外,Javadoc 的输出现在符合兼容 HTML5 标准。并且每个 Javadoc 页面都包含有关 JDK 模块类或接口来源的信息。
JAVA9新特性(二)

改进的Stream API

在 Java 9 中,Stream API 通过新增方法, 实现有限制的从 Stream 中添加或者移除元素,遍历 Stream 中的元素,以及通过扩展 Java SE API 集合实现从空值创建流的功能。
长期以来,Stream API 都是 Java 标准库最好的改进之一。通过这套 API 可以在集合上建立用于转换的申明管道。在 Java 9 中它会变得更好。Stream 接口中添加了 4 个新的方法:dropWhile, takeWhile, ofNullable。还有个 iterate 方法的新重载方法,可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代
除了对 Stream 本身的扩展,Optional 和 Stream 之间的结合也得到了改进。现在可以通过 Optional 的新方法 stram 将一个 Optional 对象转换为一个(可能是空的) Stream 对象:在组合复杂的 Stream 管道时,将 Optional 转换为 Stream 非常有用。

HTTP 2

Java 9采用了全新的HTTP客户端API,这些API支持HTTP/2协议和WebSocket协议,并且替换了遗留的HTTPURLConnectionAPI。这些改变并不应该在Java 9中完成。这些API可以从Incubator(孵化器)模块中获取。因此在默认情况下,这个模块是不能根据classpath获取的,需要使用–add-modules命令选项配置这个模块,将这个模块添加到classpath中。

创建一个HTTPRequest请求和获取异步的响应:
JAVA9新特性(二)

多版本兼容JAR

Java 9提供了一种为新API和新的Java语言结构执行此操作的方法: 多版本JAR文件 。多版本JAR文件看起来就像之前的JAR文件一样,但多了一个关键的补充:在JAR文件中可以放置使用最新Java 9功能的类。如果运行Java 9,则JVM会识别这个类并忽略同一个包中其他同名的类。
JAVA9新特性(二)
在上述场景中, multirelease.jar 可以在 Java 9 中使用, 不过 Helper 这个类使用的不是顶层的 multirelease.Helper 这个 class, 而是处在“META-INF/versions/9”下面的这个。这是特别为 Java 9 准备的 class 版本,可以运用 Java 9 所提供的特性和库。同时,在早期的 Java 诸版本中使用这个 JAR 也是能运行的,因为较老版本的 Java 只会看到顶层的这个 Helper 类。

废弃和遗弃的API

Java 9 废弃或者移除了几个不常用的功能。其中最主要的是 Applet API,现在是标记为废弃的。随着对安全要求的提高,主流浏览器已经取消对 Java 浏览器插件的支持。HTML5 的出现也进一步加速了它的消亡。开发者现在可以使用像 Java Web Start 这样的技术来代替 Applet,它可以实现从浏览器启动应用程序或者安装应用程序。
同时,appletviewer 工具也被标记为废弃。
Java 9 还废弃了并行标记扫描(CMS,Concurrent Mark Sweep)垃圾回收器,在未来的发布版本中将进一步停止支持。其目的是加速 HotSpot 虚拟机中其他垃圾回收器的发展。低暂停 G1(low-pause G1) 回收器将是 CMS 的长期替代品。
同时,之前在 JDK 8 中废弃的垃圾收集组合在 JDK 9 中已经删除。这包括很少使用的组合,例如增量 CMS,ParNew + SerialOld,DefNew + CMS,这些给垃圾收集器的代码库增加了额外的复杂性。
Java 9 也忽略了 Java 导入语句的警告,以有助于大型代码库维持更干净的 lint 警告。在这些代码库中,废弃的功能通常还需要继续使用一段时间,代码中导入废弃类或者方法,如果是开发者有意为之,并且通过注解抑制这些警告信息,那么警告信息将不会显示出来。
在 Java 9 中同时移除的还有通过 Multiple JRE(mJRE)功能在启动时选择 JRE 版本 的功能。这个功能很少使用,同时使 Java 启动器的实现复杂化,自从在 JDK 5 开始出现以来,一直没有完整的文档描述。
Oracle 已经移除 JVM TI(Tool Interface)hprof(Heap Profiling) 代理,它在 JVM 中已经被代替。jhat 工具也被移除,它早已被更好用的堆栈可视化和分析工具所代替。

改进的代码编译

Java 9 的升级带来了几个代码编译的新功能,其中最主要的是 AoT(ahead-of-time)编译。虽然仍处于试验阶段,但这个功能使得 Java 应用在被虚拟机启动之前能够先将 Java 类编译为原生代码。此功能旨在改进小型和大型应用程序的启动时间,同时对峰值性能的影响很小。
JIT(Just-in-time)编译器速度很快,但是 Java 项目现在变得很大很复杂,因此 JIT 编译器需要花费较长时间才能热身完,而且有些 Java 方法还没法编译,性能方面也会下降。AoT 编译就是为了解决这些问题而生的。
但是 Java 技术供应商 Excelsior 的营销总监 Dmitry Leskov 担心 AoT 编译技术不够成熟,希望 Oracle 能够等到 Java 10 时有个更稳定版本才发布。
Java 9 同时还提供了 Oracle 智能编译部署的阶段二功能。这个功能包括改进了 s javac 工具的稳定性和可移植性,从而能够被 JVM 默认使用。这个工具也将会做得更通用,从而可以使用在除 JDK 之外的其他大型项目中。JDK 9 还更新了 javac 编译器以便能够将 java 9 代码编译运行在低版本 Java 中。
另一个新的同时也是试验性的功能是 JVMCI(Java-level JVM Compiler Interface)。通过这个接口,用 Java 编写的编译器可以被 JVM 当作动态编译器使用。JVMCI 的 API 提供访问虚拟机结构,安装编译过的代码,以及插入 JVM 编译系统中的机制。
使用 Java 编写的 JVM 编译器相比已有的用 C 或者 C++ 编写的编译器,能够在保持高质量的同时更容易维护和改进。因此,使用 Java 编写的编译器本身应该更容易维护和改进。其他使用 Java 编写编译器的尝试包含 Graal 项目和 Metropolis 项目。
新的编译器控制能力旨在为 JVM 编译器提供细粒度和方法上下文相关的控制,让开发者在运行时不降低性能的前提下修改编译器控制选项。这个工具还支持为 JVM 编译器存在的 bug 提供解决方法。

紧凑字符串(底层的实现)

采用一个更节省空间的内部表示为字符串。 在此之前,字符串类存储字符需要使用两个字节存储每个字符(16位)。新的内部表示字符串类是一个字节数组+一个encoding-flag字段。

Try-with-Resource

在Java 7中,try-with-resouces语法要求为每一个资源声明一个新的变量,而且这些资源由try-with-resources语句进行管理。
在就Java 9中,有另外一个改进:如果一个资源被final或者等效于final变量引用,则在不需要声明一个新的变量的情况下,try-with-resources就可以管理这个资源。
JAVA9新特性(二)

钻石(diamond)操作符<>

Java 7中钻石操作符不允许在匿名类上使用。但在Java 9中改善了这一情况,允许钻石操作符在匿名类上使用。下面的例子只有在Java 9中才能通过编译。
JAVA9新特性(二)

单个下划线不再是合法字符

JAVA9新特性(二)

@SafeVarargs

@SafeVarargs注释可以仅适用于方法不能被覆盖。之前只能在static或final以及构造方法上,在Java SE 9中,多加入私有实例方法。
JAVA9新特性(二)

@Deprecated增强

@Deprecated(since= “version”)
version是当API被弃用的版本号,表面该API将被弃用在版本的Java SE平台。默认值为空字符串(“”)。
@Deprecated(forRemoval =)
forRemoval = true表明,该API在将来发布的版本中移除。
forRemoval = false建议代码应该不再使用这个API; 然而,目前没有计划把API删除。 默认值为false。
@Deprecated(since=”9”, forRemoval=true)
表明此API将于版本9删除

Process API

在Java 9之前,可以启动本地进程并使用其输入,输出和错误流。 但是,无法使用未启动的本地进程,无法查询进程的详细信息。 为了更紧密地处理本地进程,Java开发人员不得不使用Java Native Interface(JNI)来编写本地代码。 Java 9使这些非常需要的功能与本地进程配合使用。
Java 9向Process API添加了一个名为ProcessHandle的接口。 ProcessHandle接口的实例标识一个本地进程; 它允许查询进程状态并管理进程。