New Features in Java 9 – Java 9的新功能

最后修改: 2016年 10月 11日


1. Overview


Java 9 comes with a rich feature set. Although there are no new language concepts, new APIs and diagnostic commands will definitely be interesting to developers.

Java 9带有丰富的功能集。虽然没有新的语言概念,但新的API和诊断命令肯定会让开发者感兴趣。

In this writeup we’re going to have quick, high level look at some of the new features; a full list of new features is available here.


2. Modular System – Jigsaw Project

2.模块化系统 – 拼图项目

Let’s start with the big one – bringing modularity into the Java platform.


A modular system provides capabilities similar to OSGi framework’s system. Modules have a concept of dependencies, can export a public API and keep implementation details hidden/private.


One of the main motivations here is to provide modular JVM, which can run on devices with a lot less available memory. The JVM could run with only those modules and APIs which are required by the application. Check out this link for a description of what these modules are.


Also, JVM internal (implementation) APIs like com.sun.* are no longer accessible from application code.


Simply put, the modules are going to be described in a file called located in the top of java code hierarchy:


module {
    requires com.baeldung.java9.modules.engines;

Our module car requires module engine to run and exports a package for handling.


For more in-depth example check OpenJDK Project Jigsaw: Module System Quick-Start Guide.

关于更深入的例子,请查看OpenJDK Project Jigsaw:模块系统快速启动指南

3. A New HTTP Client


A long-awaited replacement of the old HttpURLConnection.


The new API is located under the package.


It should support both HTTP/2 protocol and WebSocket handshake, with performance that should be comparable with the Apache HttpClient, Netty and Jetty.

它应该同时支持HTTP/2协议WebSocket握手,其性能应该与Apache HttpClientNettyJetty相近。

Let have a look at this new functionality by creating and sending a simple HTTP request.


Update: The HTTP Client JEP is being moved to Incubator module, so it is no longer available in the package and instead is available under jdk.incubator.http.

更新:HTTP 客户端 JEP正被转移到孵化器模块中,因此它不再在包中提供,而是在jdk.incubator.http.中提供。

3.1. Quick GET Request


The API uses the Builder pattern, which makes it really easy for quick use:


HttpRequest request = HttpRequest.newBuilder()
  .uri(new URI(""))

HttpResponse<String> response = HttpClient.newHttpClient()
  .send(request, HttpResponse.BodyHandler.asString());

4. Process API


The process API has been improved for controlling and managing operating-system processes.


4.1. Process Information


The class java.lang.ProcessHandle contains most of the new functionalities:


ProcessHandle self = ProcessHandle.current();
long PID = self.getPid();
ProcessHandle.Info procInfo =;
Optional<String[]> args = procInfo.arguments();
Optional<String> cmd =  procInfo.commandLine();
Optional<Instant> startTime = procInfo.startInstant();
Optional<Duration> cpuUsage = procInfo.totalCpuDuration();

The current method returns an object representing a process of currently running JVM. The Info subclass provides details about the process.


4.2. Destroying Processes


Now – let’s stop all the running child processes using destroy():


childProc = ProcessHandle.current().children();
childProc.forEach(procHandle -> {
    assertTrue("Could not kill process " + procHandle.getPid(), procHandle.destroy());

5. Small Language Modifications


5.1. Try-With-Resources


In Java 7, the try-with-resources syntax requires a fresh variable to be declared for each resource being managed by the statement.

在Java 7中,try-with-resources语法要求为语句所管理的每个资源声明一个新变量。

In Java 9 there is an additional refinement: if the resource is referenced by a final or effectively final variable, a try-with-resources statement can manage a resource without a new variable being declared:

在Java 9中,有一个额外的改进:如果资源被一个final或有效的final变量所引用,try-with-resources语句可以管理一个资源而不需要声明一个新的变量。

MyAutoCloseable mac = new MyAutoCloseable();
try (mac) {
    // do some stuff with mac
try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
   // do some stuff with finalCloseable
} catch (Exception ex) { }

5.2. Diamond Operator Extension


Now we can use diamond operator in conjunction with anonymous inner classes:


FooClass<Integer> fc = new FooClass<>(1) { // anonymous inner class
FooClass<? extends Integer> fc0 = new FooClass<>(1) { 
    // anonymous inner class
FooClass<?> fc1 = new FooClass<>(1) { // anonymous inner class

5.3. Interface Private Method


Interfaces in the upcoming JVM version can have private methods, which can be used to split lengthy default methods:


interface InterfaceWithPrivateMethods {
    private static String staticPrivate() {
        return "static private";
    private String instancePrivate() {
        return "instance private";
    default void check() {
        String result = staticPrivate();
        InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {
            // anonymous class
        result = pvt.instancePrivate();

6. JShell Command Line Tool


JShell is read–eval–print loop – REPL for short.

JShell是read-eval-print循环 – 简称REPL。

Simply put, it’s an interactive tool to evaluate declarations, statements, and expressions of Java, together with an API. It is very convenient for testing small code snippets, which otherwise require creating a new class with the main method.


The jshell executable itself can be found in <JAVA_HOME>/bin folder:


|  Welcome to JShell -- Version 9
|  For an introduction type: /help intro
jshell> "This is my long string. I want a part of it".substring(8,19);
$5 ==> "my long string"

The interactive shell comes with history and auto-completion; it also provides functionality like saving to and loading from files, all or some of the written statements:


jshell> /save c:\develop\JShell_hello_world.txt
jshell> /open c:\develop\JShell_hello_world.txt
Hello JShell!

Code snippets are executed upon file loading.


7. JCMD Sub-Commands


Let’s explore some of the new subcommands in jcmd command line utility. We will get a list of all classes loaded in the JVM and their inheritance structure.


In the example below we can see the hierarchy of java.lang.Socket loaded in JVM running Eclipse Neon:

在下面的例子中,我们可以看到在运行Eclipse Neon的JVM中加载的java.lang.Socket的层次结构。

jdk-9\bin>jcmd 14056 VM.class_hierarchy -i -s
|  implements (declared intf)
|  implements java.lang.AutoCloseable/null (inherited intf)
|  |--org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket
|  |  implements java.lang.AutoCloseable/null (inherited intf)
|  |  implements (inherited intf)
|  |
|  |  implements java.lang.AutoCloseable/null (inherited intf)
|  |  implements (inherited intf)

The first parameter of jcmd command is the process id (PID) of the JVM on which we want to run the command.


Another interesting subcommand is set_vmflag. We can modify some JVM parameters online, without the need of restarting the JVM process and modifying its startup parameters.


You can find out all the available VM flags with subcommand jcmd 14056 VM.flags -all

你可以通过子命令jcmd 14056 VM.flags -all找出所有可用的VM标志。

8. Мulti-Resolution Image API

8.Multi-Resolution Image API

The interface java.awt.image.MultiResolutionImage encapsulates a set of images with different resolutions into a single object. We can retrieve a resolution-specific image variant based on a given DPI metric and set of image transformations or retrieve all of the variants in the image.


The java.awt.Graphics class gets variant from a multi-resolution image based on the current display DPI metric and any applied transformations.


The class java.awt.image.BaseMultiResolutionImage provides basic implementation:


BufferedImage[] resolutionVariants = ....
MultiResolutionImage bmrImage
  = new BaseMultiResolutionImage(baseIndex, resolutionVariants);
Image testRVImage = bmrImage.getResolutionVariant(16, 16);
assertSame("Images should be the same", testRVImage, resolutionVariants[3]);

9. Variable Handles


The API resides under java.lang.invoke and consists of VarHandle and MethodHandles. It provides equivalents of java.util.concurrent.atomic and sun.misc.Unsafe operations upon object fields and array elements with similar performance.


With Java 9 Modular system access to sun.misc.Unsafe will not be possible from application code.

随着Java 9模块化系统对sun.misc.Unsafe的访问将无法从应用程序代码中实现。

10. Publish-Subscribe Framework


The class java.util.concurrent.Flow provides interfaces that support the Reactive Streams publish-subscribe framework. These interfaces support interoperability across a number of asynchronous systems running on JVMs.

java.util.concurrent.Flow类提供了支持Reactive Streams>发布-订阅框架的接口。这些接口支持在JVM上运行的一些异步系统的互操作性。

We can use utility class SubmissionPublisher to create custom components.


11. Unified JVM Logging


This feature introduces a common logging system for all components of the JVM. It provides the infrastructure to do the logging, but it does not add the actual logging calls from all JVM components. It also does not add logging to Java code in the JDK.


The logging framework defines a set of tags – for example, gc, compiler, threads, etc. We can use the command line parameter -Xlog to turn on logging during startup.


Let’s log messages tagged with ‘gc’ tag using ‘debug’ level to a file called ‘gc.txt’ with no decorations:


java -Xlog:gc=debug:file=gc.txt:none ...

-Xlog:help will output possible options and examples. Logging configuration can be modified runtime using jcmd command. We are going to set GC logs to info and redirect them to a file – gc_logs:


jcmd 9615 VM.log output=gc_logs what=gc

12. New APIs


12.1. Immutable Set


java.util.Set.of() – creates an immutable set of a given elements. In Java 8 creating a Set of several elements would require several lines of code. Now we can do it as simple as:

java.util.Set.of() – 创建一个指定元素的不可变的集合。在Java 8中,创建一个包含多个元素的集合需要几行代码。现在我们可以简单地做到这一点。

Set<String> strKeySet = Set.of("key1", "key2", "key3");

The Set returned by this method is JVM internal class: java.util.ImmutableCollections.SetN, which extends public java.util.AbstractSet. It is immutable – if we try to add or remove elements, an UnsupportedOperationException will be thrown.


You can also convert an entire array into a Set with the same method.


12.2. Optional to Stream

12.2.可选的流媒体 gives us an easy way to you use the power of Streams on Optional elements:为我们提供了一种简单的方法,可以在Optional元素上使用流的力量。

List<String> filteredList =

13. Conclusion


Java 9 will come with a modular JVM and lots of other new and diverse improvements and features.

Java 9将配备一个模块化的JVM和许多其他新的和多样化的改进和功能。

You can find the source code for the examples over on GitHub.