Java 10 : what’s new ?
Now that java 10 is out, it’s time to look at all the new functionalities of this version. Like my previous article on Java 9, I will focus on the changes that will impact developers that uses Java leaving aside the changes that are internal/very small/on rarely used API.
The new “release train”
A very special novelty is the way Java will be released since Java 10 : Java will evolve from a feature release each 2 years (that was close to each 3 years un reality) to a release train with a new release each 6 months.
Previously, a set of functionalities was defined to fit in a version of Java, this version was delivered when all those functionalities will be ready, there was a lot of new things in a version of Java which lead to diffculties to deliver it and a huge gap for the users in each version.
Starting with Java 10 : a new version each 6 months in release train : all functionalities will be developped on specific developement branch, when a functionality is ready it will be merged on the main branch. At the release date, everything that has been merged in the main branch will be part of the release. With this king of release mechanism, we will have more small release in a regular way. Last point, each version of Java will not have a very long support period. The support period will be until the next release (so 6 months) except for Long Term Support (LTS) releases that will offrer at least three years of support. Java 11 will be the first LTS release.
We can regret that the first LTS will be 11 and not the version 9 that brings a lot of new changes but will only be supported 6 months so nobody will use it in production. As there will be no overlap between two non-LTS releases people will need to upgrade to the new version as soon as it’s been out or will stay on LTS releases : in this case Java will evolve to a feature release each 2-3 years to a release train each … 3 years …
This release train and LTS version scheme is close to the one for Ubuntu, but Java keep it’s previous version number mechanism (a version number based on dates has been considered then abandoned).
See the article from Mark Reinhold that explains in details this new release train and it’s motivation : https://mreinhold.org/blog/forward-faster
More info in the JEP : http://openjdk.java.net/jeps/322
What’s new in the language for developers
Local-Variable Type Inference
This is THE big new functionality of Java 10 : the possibility to use the keyword var instead of a standard variable declaration, inside a method (local variable) when the type can be inferred by the compiler. Var can also be used in the declaration of for loop and with the try-with-resource.
Java stay a statically typed language, but when we declare a variable then instantiate it in the same line, the type declaration is redondant! The keyword var will replace it.
In Java 9 :
MyComplexType obj = new MyComplexType(); Map<String,List<MyComplexType>> map = new HashMap<String,List<MyComplexType>>();
In Java 10 with var :
var obj = new MyComplexType(); var map = new HashMap<String,List<MyComplexType>>();
Better visibility (among others, two variables will be indented in the same level), less ceremony, concision, …
For the moment, the var keyword will be limited to variables locals to a method and there is no “immutable” equivalent, the work on immutability in Java being in the process of reflection it will have been premature to propose a keyword for final variable (val or let …).
Stuart Marks published guidelines on the var keyward usage : http://openjdk.java.net/projects/amber/LVTIstyle.html
More info in the JEP : http://openjdk.java.net/jeps/286
Copy factory methods
The Collection API has been enhanced with static methods that allow the copy of existing collections : List.copyOf(), Set.copyOf(), and Map.copyOf().
In the three cases, the returned collection will be an immutable collection. If the existing collection was already an immutable one, the collection will be directly returned (because there is no point in creating a copy of an immutable collection that will be itself immutable …) else a new immutable one will be created.
Warning, the collection is immutable not the object inside the collection!
Here under, for the example, the current implementation of List.copyOf():
static <E> List<E> copyOf(Collection<? extends E> coll) { if (coll instanceof ImmutableCollections.AbstractImmutableList) { return (List<E>)coll; } else { return (List<E>)List.of(coll.toArray()); } }
More info in the JIRA tiket : https://bugs.openjdk.java.net/browse/JDK-8177290
Collectors to unmodifiable List
In the same mouvement thant the predecing change, the collectors of the Stream API has been enhanced to allow the creation of immutable collections :
- Collectors.toUnmodifiableList()
- Collectors.toUnmodifiableSet()
- Collectors.toUnmodifiableMap(keyFunc, valueFunc)
- Collectors.toUnmodifiableMap(keyFunc, valueFunc, mergeFunc)
More info on the JIRA ticket : https://bugs.openjdk.java.net/browse/JDK-8184690
Optional.orElseThrow()
Optional.orElseThrow() is now the prefered way (in detriement to Optional.get()) for retrieving an element in an Optional. It’s name crearly references the fact that if there is no element, an exception will be thrown (this is the case for Optional.get() but often forgiven by the developers that uses it).
This is part of a larger reflection on Optional, we should saw more addins to this classe in the next releases …
More info in the JIRA ticket : https://bugs.openjdk.java.net/browse/JDK-8140281
Reader.transferTo(Writer)
A new method on the Reader class to directly transfert all characters from a Reader to a Writer :
Reader reader = new FileReader("from.txt"); Writer writer = new FileWriter("to.txt"); reader.transferTo(writer);
The main changes regarding performance
Parallel Full GC for G1
This is the main change regarding performance.
G1 is, since Java 9, the per default Garbage Collector algorithm. In G1, when the collector didn’t succeed in cleaning the heap quickly enough concurrently, it triggers a Full GC that is mono-threaded. Since Java 10, this implementation has been changed in a multi-threaded one, the number of threads can be defined by -XX:ParallelGCThreads
More info in the JEP : http://openjdk.java.net/jeps/307
Thread-Local Handshakes
Untill Java 9, the only way to be able to make actions on multiple thread in the same time (gathering a thread dump, lock management, …) was to put all the threads in a safepoint. This is a costly operation that need to coordinate all the threads of the application.
Since java 10 : the Handshakes mechanism allow to execute callbacks on the threads without going throught a safepoint.
This low level functionality open the doors to mode optimizations inside the JVM that we should see in the next releases.
More info in the JEP : http://openjdk.java.net/jeps/312
Miscelanious
Experimental Java-Based JIT Compiler
This new functionality allow to change the Just In Time (JIT) compiler of Java to a JIT written in Java : Graal
The JIT is the part of the JVM that allows to optimize running code inside the JVM during it’s execution, the current one is written in C++ and starts to be difficult to maintain.
Grall is a new Oracle project that is part on a larger one : Metropolis, whose purpise it to do Java on Java. So to make Java works with a JVM written in Java (today the JVM is mainly written in C++). Graal is a compiler, written in Java, who from Java bytecode (compiled Java) can generate optimized natif code. Its Java implementation makes it easy to write and maintain. It can be seen as the future of the JVM JIT, it is now in beta phase but can be used easily since java 10 with these JVM options :
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
A really good article introducing Graal : http://chrisseaton.com/truffleruby/jokerconf17/
More info on the JEP : http://openjdk.java.net/jeps/317
Heap Allocation on Alternative Memory Devices
From one side, our applications needs more and more memory, and even if our servers have more and more memories … it’s never enough. In the opposite, it now exists storage devices that have performances close to DRAM.
This new functionality, implemented by Intel (who give an implementation for there hight performance flash card NV-DIM 3D XPoint) allow to start a JVM by using a Heap not in RAM.
More info on the JEP : http://openjdk.java.net/jeps/316
Application Class-Data Sharing
This functionality allow to share between multiple JVM running on the same machine the classes meta-information (class metadata, a part of the metastore). It optimizes the starting and the footprint of these JVMs.
This functionality can be very handful in the time of cloud and containerization …
More info on the JEP : http://openjdk.java.net/jeps/310
To go further
An exhaustive list (I think) of all the changes of this release : https://www.azul.com/109-new-features-in-jdk-10