Java 10: inference, classes, APIs and methods
Java 9 introduced significant changes to the structure and architecture of language. Oracle’s policy seems to be consolidating towards a direction that leads to the release of more frequent language updates than in the past.
We should not, therefore, be surprised at the release of version 10 so shortly in time from the previous one. In this article, we want to illustrate the changes in the new release that we consider more interesting.
Inference of the declared data type for a local variable
The diamond operator, introduced with the Java 7 version, is part of that set of changes aimed at reducing the verbosity of the language. Consider the following example of Java 7 pre:
List <String> list = new ArrayList <String> ();
Using the diamond operator allows a slightly more compact code to be used:
List <String> list = new ArrayList <> ();
The interesting novelty of Java 10 , in this context, is the introduction of the keyword varthat allows the inference of the type of data declared for a local variable:
var list = new ArrayList <> (); var list = new ArrayList <String> ();
In the first case one ArrayList of objects is deducted Object while in the second case one ArrayListof objects String. We can see how the code acquires greater compactness.
The use of the keyword varis subject to some restrictions: it can not be used in the declaration of variables without initialization or with initialization at the value null:
var identificatore; // Non consentito var identificatore1, identificatore2 = 0; // Non consentito var identificatore = null; // Non consentito
As a last note on this new keyword, we point out that its use is possible for variable, method and package names but not for a class name:
public class var {..} // Non consentito
The Optional class
Remaining in the context of verbosity reduction, the class Optional is equipped with the method orElseThrow()that avoids the use of the method orElseThrow(Exception)when the exception NoSuchElementExceptionis what we need:
Optional<String> optional = new Optional<String>(); var value = optional.orElseThrow();
instead of:
String value = optional.orElseThrow(NoSuchElementException::new);
API and methods in Java 10
Within the APIs for the creation of non-editable lists and maps, the types List, Setand Maphave been provided with the method copyOf()that allows to obtain a non-editable copy of a list, set or map starting from an existing one:
var lista = new ArrayList<>; lista.add("Str1"); lista.add ( "Str2"); var list2 = list.copyOf (list); lista2.add ( "Str3"); // will produce an exception
To the sphere of these modifications belongs the introduction of the methods toUnmodifiableList(), toUnmodifiableSet()and toUnmodifiableMap() for the class Collectorsof the package Streams:
var stream = lista.stream (). collect (Collectors.toUnmodifiableList ());
Java 10: performance and Docker support
Performance improvements
We move now to improvements that affect the performance of the JVM. The product code for an enhanced for loop up to version 9 of Java can be illustrated with the following example:
List <String> values = new ArrayList <> (); for (String value: values) System.out.println (value);
which is translated into:
List <String> values = new ArrayList <> (); String value; for (Iterator <String> iterator = values.iterator (); iterator.hasNext (); value = iterator.next ()) System.out.println (value);
In Java 10, type variables Iteratorare declared outside the loop and initialized to the value as nullsoon as the operation is finished. The equivalent code generated is therefore:
Iterator iterator = values.iterator (); String value; for (; iterator.hasNext ();) { value = (String) iterator.next (); } value = null; iterator = null;
In this way the variables no longer used are immediately made eligible for removal by the garbage collector .
The garbage collector G1 ( Garbage-First ) is designed for heap sizes greater than 4 GB and divides the heap size into different regions. The G1 uses a concurrent global tagging step to determine the activity of objects throughout the heap. At the end of this phase the G1 knows which regions are for the most part empty and first removes the unreachable objects present in these regions producing, in general, a large amount of free space (hence the name Garbage-First ).
G1 also uses a pause forecast model to satisfy the user-defined pause time. Java 9 made the G1 default by default, while the new Java 10 version added a complete Parallel Garbage Collector support to G1 , which uses multiple threads to analyze the heap space, thus improving the worst case latency.
The number of parallel threads can be controlled via the XX:ParallelGCThreadsJVM parameter.
Docker
We conclude by highlighting the improvements related to the Docker technology. A Docker system uses the Linux kernel to isolate processes in such a way that they can be run independently. This independence is the goal of containers: the ability to run multiple processes and applications separately to take advantage of the existing infrastructure while preserving the level of security that would be in the presence of separate systems.
The Java 10 JVM, when running on a Linux system, is able to detect its execution inside a Docker container. The JVM has three new options that provide container users with better system memory control.
In addition, bugs have been fixed for linking host processes and Java processes running on the Docker container.