Three years after the release of Java 8, Java 9 has finally seen light of day. With more than 80 new features available at this address: http://openjdk.java.net/projects/jdk9/. (This is a very rich version in terms of content.)
You will be able to discover through this article a summary of the main new features that this version brings.

BRIEF SUMMARY ON JAVA 8

« Java 8 made Java great again?” Thanks to Java 8, Java has been voted « language of the year » in 2015 according to the TIOBE index. It had not been since 2005.

tiobe capturing
This version has brought a lot changes and news features in the way we program with Java, here is a list:

  • The lambda expressions,
  • Method references,
  • Functional programming,
  • The Stream and Collector API,
  • The Date & Time API,
  • The Optional class,
  • CompletableFuture,
  • Permgen (Permanent Generation) replaced by Metaspace,
  • Static and default methods on interfaces.

Not to mention JavaFX, Oracle’s maintained graphic library replacing Swing and AWT, which has also been greatly updated with the arrival of this version.

JAVA 9’s New Features

Java 9 has been the most controversial version. Indeed, it is the first time that the JCP executive committee, « Java Community Process » (organization that coordinates the evolution of Java language), votes no for its release. However, it was still released in September 2017.

A FEW JAVA 9 PREJUDICES

We are hearing a lot of things concerning Java 9, let’s refute a few things:

  • « The classPath is replaced by the module-path »: False, both coexist.
  • « The application code must be modular »: This is the final goal, but today it is still possible to use non-modular code.
  • « sun.misc.Unsafe is removed »: False, it is one of the goals, but it still lacks alternative replacement solutions to certain features.
  • « The majority of the existing code will not need to be modified »: True, there will be changes needing to be made, but the majority of the code will remain the same.

JAVA 9’S ADVANTAGES

Even though the committee refused to release it, Java 9 has many advantages. Here are a few:

SYNTAX IMPROVEMENT

  • Final variables in « try-with-resources »:

Final and in fact final variables can be placed in « try-with-resources » blocks, through Java 9. This will give you more options for automatic resource management.
In java 7 with the addition of the block « try-with-resources » the syntax was written as follows:

try (BufferedReader reader1 = new BufferedReader(new FileReader("fichier1.txt"));
     BufferedReader reader2 = new BufferedReader(new FileReader("fichier2.txt"));
     BufferedReader reader3 = new BufferedReader(new FileReader("fichier3.txt"))) {
    
    System.out.println(reader1.readLine());
    System.out.println(reader2.readLine());
    System.out.println(reader3.readLine());
}

But now, with Java 9, it is possible to declare « Closeable » resources outside the try block if they are final or actually final. It is also possible, in order to facilitate the readability, to create utility methods for the instantiation of resources, in the code block below with Java 9. To instantiate our reader 1 we used a utility method. The other two readers are, for their part, directly instantiated but with the try-with-resources block, as the readers are final it is sufficient to list them in the try so that they are automatically closed in the finally:

BufferedReader reader1 = getNewReader();
BufferedReader reader2 = new BufferedReader(new FileReader("fichier2.txt"));
BufferedReader reader3 = new BufferedReader(new FileReader("fichier3.txt"));

try (reader1; reader2; reader3) {
    System.out.println(reader1.readLine());
    System.out.println(reader2.readLine());
    System.out.println(reader3.readLine());
}
  • The »private » methods in the interfaces:

After the static and default methods in Java 8, Java 9 adds the private methods in the interfaces. The two main advantages to this are:
– Allows to facilitate the encapsulation and to avoid duplicating certain parts of the code,
– Only exposes the desired methods.

  • The diamond operator in the internal Anonymous classes:

The diamond operator can now be used in internal anonymous classes:

UnaryOperator<Integer> increment = new UnaryOperator<>() {
    @Override
    public Integer apply(Integer integer) {
        return integer + 1;
    }
};

System.out.println(increment.apply(1));

With this code you will no longer have the compile error “ ‘<> ‘cannot be used with anonymous classes” and your code will be easier to read.

  • The @SafeVarargs annotation can now be used on private instance methods:

This annotation makes it possible to define that the body method or the constructor of the annotated method does not perform potentially dangerous operations on its parameter varargs. Now the annotation can be used on private instance methods.

TOOLS AND API

  • Factories for immutable collections:

– List.of (),
– Set.of (),
– Map.of ().
In Java 8 an immutable list would have been created in this way:

List<String> chiffres = Arrays.asList("1", "2", "3", "4");

chiffres = Collections.unmodifiableList(chiffres);

From now on with Java 9, it is enough to use the .of method of the interface List:

List<String> chiffresImmutables = List.of("1", "2", "3", "4");

Usage is similar for the Set.of () API and Map.of () API.

  • The addition of APIs on the Process class allows:
    – to identify the direct child or descendant processes,
    – to obtain the PID of this Process,
    – to return a “snapshot” of information regarding this process,
    – to obtain a « completable future » to receive an asynchronous notification.
  • The addition of Reactive stream with the API Flow allows reactive pattern standardization in 4 interfaces:
    – Publisher,
    – Subscriber,
    – Subscription,
    – Processor.
  • The VarHandle API provides reading and writing access to variables, somehow a typed reference to the variables of a class, the purpose here is to replace some features of Unsafe API.

Here is an example of its use on a variable:

Private static class Arbre {
    float taille;
}

static final VarHandle VH_ARBRE_FIELD_TAILLE;

static {
    try {
        VH_ARBRE_FIELD_TAILLE = MethodHandles.lookup()
                                             .in(Arbre.class)
                                             .findVarHandle(Arbre.class, "taille", float.class);
    } catch (Exception e) {
        throw new Error(e);
    }
}

Thus, it is possible to retrieve the value of an attribute and modify it without going through the Unsafe API:

Arbre arbre = new Arbre();
arbre.taille = 3.4f;

System.out.println(VH_ARBRE_FIELD_TAILLE.get(arbre));
VH_ARBRE_FIELD_TAILLE.set(arbre, 4.0f);
System.out.println(VH_ARBRE_FIELD_TAILLE.get(arbre));

Obtained result:
3.4
4.0
We saw in the example the use in reading by using the « get » and in writing with the « set », there is also the writing conditioned by a value with the call of the method « compareAndSet »:
If the value passed in parameter corresponds to the value of the attribute it will be updated with the value passed in the third parameter:

VH_ARBRE_FIELD_TAILLE.compareAndSet(arbre, 4f, 2f);
System.out.println(VH_ARBRE_FIELD_TAILLE.get(arbre));

The new tools:

  • JShell is a command line REPL type tool that allows you to run Java code in a simplified way, much like you would with python.
  • Jlink is also a command-line tool that allows you to create your own lightweight JRE that contains only the modules we want to use.
  • Jdeprscan scans classes to check the deprecated API usage of Java.

IMPROVING THE JVM

On each version we have improvements of the JVM, more precisely with this version better performance are observed and this thanks to several optimizations:

  • Compact String
    We are no longer on a char array, but on a byte array, the CPU consumption has increased, but the size of the strings has greatly reduced.
  • String concatenation with InvokeDynamic
    The concatenation byte-code has been replaced by an InvokeDynamic call as well as a bootstrap method that will generate the concat call.
  • G1 used as the default garbage collector
    Numerous improvements have been made to G1 in JDK 8 and its updates, and further improvements have been made in JDK 9. The introduction of simultaneous class unloading (JEP 156) in JDK 8u40 has made G1 a complete garbage collector, ready to be used by default.
  • Segmentation of the cache code
    The compiled code has been split into separate caches, each cache segment corresponds to a particular type.
  • Unification of the JVM log system

MODULES

The modules are perceived as constraining with an impression of loss of freedom in comparison to what has been done for more than 20 years.
Here is a small summary of some of the constraints and benefits of this new design:

Java - article
Now let’s tackle the types of modules, we have several to demonstrate:

  • The platform modules that contain the modules of the JRE,
  • App Named Modules with Modular Jar in the path module,
  • The Unnamed module, a single module that contains the jars of the class path, has the particularity of having access to:
    – All packages exported by all the other modules available in the module-path,
    – All the jars of the classpath (all the other types present in this unnamed module).
  • Automatic modules: automatic modules see all their public types exported. A module using an automatic module can therefore use any public type, in the same way that in java 8 we used a jar.

To be able to benefit from all these new features and to embark on the much shorter release cycle offered by Oracle, it will be necessary to update the versions of our JDK … You will be able to find all the needed information in our next article: A must: migration to Java 9.