Java 10 Features – Overview
Java 10 is the fastest release of a java version in its 23-year history. Java has been criticized for its slow growth and evolution, but Java 10 just shattered that concept. Java 10 is a release with many futuristic changes, the scope, and impact of which may not be obvious but are far-fetching. In this article, we will discuss the various features added in Java10 release. Before that, let’s go over some changes introduced to java release model.
Long Term Support Model – Java 10 Features
Starting 2017, Oracle & the Java community announced its shift to a new 6-month cadence for Java. It moved to a Long Term Support (LTS) model for Oracle Java SE products. What does this mean? LTS version of the products will offer premier and sustained support from Oracle and it will be targeted every 3 years. Each Java release is modeled after one or two major feature, these features drive the release. Any obstacle postpones the release and late to market. Project Jigsaw was a major feature of Java 9, it pushed out the release dates a couple of times and the release was delayed by more than 1.5 years. 6 months cadence release will follow a release train. Release train will have a schedule every 6 months. Features which make the cut get boarded on the train; else they wait for the next scheduled train.
Oracle JDK vs Open JDK
In order to be more developer-friendly, Oracle & Java community now promotes the OpenJDK binaries as primary JDK going forward. This is a big relief from earlier days, where the JDK binaries were propriety and licensed by Oracle, which had various restrictions around redistribution. Oracle will, however, keep producing their JDK, but only for long term support releases. This is a move towards being more cloud & container friendly, as the open JDK binaries can be distributed as part of a container. What does this mean? Open JDK binaries will be released every 6 months, while Oracle JDK binaries will be released every 3 years (LTS version). Which JDK binaries will be adopted? Large organizations take time to move between the versions; they cling on to the version until they can. Industry adoption for Java 6 was more than Java 7 and then Industry is gradually moving to Java 8. In my opinion, the LTS version will be the most favored ones by the enterprises. However, whether it would be the LTS version of Oracle JDK or the Open JDK is yet to know, partly because there’s a lot going on the cloud space. Java 9 & 10 are non-LTS release. Java 11 which is due in September 2018 will be a LTS release.
Java 10 Features
Time-Based Release Versioning (JEP 322)
With the adoption of the time-based release cycle, Oracle changed the version-string scheme of the Java SE Platform and the JDK, and related versioning information, for present and future time-based release models. The new pattern of the Version number is: $FEATURE.$INTERIM.$UPDATE.$PATCH $FEATURE: counter will be incremented every 6 months and will be based on feature release versions, e.g: JDK 10, JDK 11. $INTERIM: counter will be incremented for non-feature releases that contain compatible bug fixes and enhancements but no incompatible changes. Usually, this will be zero, as there will be no interim release in a six month period. This kept for a future revision to the release model. $UPDATE: counter will be incremented for compatible update releases that fix security issues, regressions, and bugs in newer features. This is updated one month after the feature release and every 3 months thereafter. The April 2018 release is JDK 10.0.1, the July release is JDK 10.0.2, and so forth $PATCH: counter will be incremented for an emergency release to fix a critical issue. New API’s have been added to get these counter values programmatically. Let’s take a look;
Version version = Runtime.version(); version.feature(); version.interim(); version.update(); version.patch();
Now, let us take a look at Java launcher which returns the version information:
$ java -version java version "10" 2018-03-20 Java(TM) SE Runtime Environment 18.3 (build 10+46) Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)
The version number format is “10” as there’s no other counter which is other than zero. The date of release is added. 18.3 can be read as the Year 2018 & 3rd Month, build 10+46 is 46th build for version 10. For a hypothetical build 93 of JDK 10.0.1, the build will be 10.0.1+939.
Local-Variable Type Inference (JEP 286)
Local-Variable Type Inference is the biggest new feature in Java 10 for developers. It adds type inference to declarations of local variables with initializers. Local type inference can be used only in the following scenarios:
- Limited only to Local Variable with initializer
- Indexes of enhanced for loop or indexes
- Local declared in for loop
Let’s take a look at its usage:
var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList // Index of Enhanced For Loop for (var number : numbers) { System.out.println(number); } // Local variable declared in a loop for (var i = 0; i < numbers.size(); i++) { System.out.println(numbers.get(i)); }
This feature enables the Java-based JIT compiler, Graal, to be used as an experimental JIT compiler on the Linux/x64 platform. This is by far the most futuristic inclusion in the Java 10 feature list. Graal was introduced in Java 9. It’s an alternative to the JIT compiler which we have been used to. It’s a plugin to the JVM, which means that the JIT compiler is not tied to JVM and it can be dynamically plugged in and replaced with any another plugin which JVMCI compliant (Java-Level JVM Compiler Interface). It also brings Ahead of Time (AOT) compilation in java world. It also supports polyglot language interpretation. “A Java-based Just in Time Compiler written in Java to convert the java bytecode to machine code.” Is it confusing? If JVM is written in Java, then don’t you need a JVM to run the JVM? The JVM can be compiled AOT and then JIT compiler can be used within JVM it for enhancing performance through live code optimization. Graal is a complete rewrite of the JIT compiler in Java from scratch. Previous JIT compiler was written in c++. It’s considered one for the final stage of evolution for any programming language. You can switch to Graal with following jvm parameters:
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
This feature helps in improving the startup footprint, extends the existing Class-Data Sharing (“CDS”) feature to allow application classes to be placed in the shared archive. JVM while starting performs some preliminary steps, one of which is loading classes in memory. If there are several jars having multiple classes, then the lag in the first request is clearly visible. This becomes an issue with serverless architecture, where the boot time is critical. In order to bring down application startup time, Application class-data sharing can be used. The idea is to reduce footprint by sharing common class metadata across different Java processes. This can be achieved by the following 3 steps: Determining the classes to archive: Use the java launcher to create a list of files to archive, this can be achieved by the following parameters:
$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld
Creating the AppCDS archive: Use java launcher to create the archive of the list of files to be used for Application CDS, this can be achieved by following parameters:
$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
Using the AppCDS archive: Use Java launcher with the following parameters to use Application CDS.
$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld
Parallel Full GC for G1 (JEP 307)
G1 garbage collector was made default in JDK 9. G1 Garbage collector avoids any full garbage collection, but when concurrent threads for collection cannot revive the memory fast enough users experience is impacted. This change improves the G1 worst-case latency by making the full GC parallel. The mark-sweep-compact algorithm from G1 collector is parallelized as part of this change and will be triggered when concurrent threads for collection can’t revive the memory fast enough.
Garbage-Collector Interface (JEP 304)
This JEP is a futuristic change. It improves the code isolation of different garbage collectors by introducing a common Garbage Collector Interface. This change provides better modularity to the Internal GC Code. It will help in the future for adding new GC without changing existing codebase, also help in removing or housekeeping of the previous GC.
Additional Unicode Language-Tag Extensions (JEP 314)
This feature enhances java.util.Locale and related APIs to implement additional Unicode extensions of BCP 47 language tags. As of Java SE 9, the supported BCP 47 U language-tag extensions are “ca” and “nu”. This JEP will add support for the following additional extensions:
- cu (currency type)
- fw (first day of week)
- rg (region override)
- tz (time zone)
In order to support these additional extensions, changes are made to various APIs to provide information based on U or additional extensions.
Root Certificates (JEP 319)
In order to promote OpenJDK and make it more appealing to community users, this feature provides a default set of root Certification Authority (CA) certificates in the JDK. This will also mean that both Oracle & Open JDK binaries will be functionally the same. Critical security components such as TLS will work by default in OpenJDK builds going forward.
Thread-Local Handshakes (JEP 312)
This is an internal JVM feature to improve performance. A handshake operation is a callback that is executed for each JavaThread while that thread is in a safepoint state. The callback is executed either by the thread itself or by the VM thread while keeping the thread in a blocked state. This feature provides a way to execute a callback on threads without performing a global VM safepoint. Make it both possible and cheap to stop individual threads and not just all threads or none.
Heap Allocation on Alternative Memory Devices (JEP 316)
Applications have become memory hungry, there’s an increase in cloud-native applications, in-memory databases, streaming applications. In order to cater to these services, there are various memory architectures available. This feature enhances the capability of HotSpot VM to allocate the Java object heap on an alternative memory device, such as an NV-DIMM, specified by the user. This JEP targets alternative memory devices that have the same semantics as DRAM, including the semantics of atomic operations, and can, therefore, be used instead of DRAM for the object heap without any change to existing application code.
Remove the Native-Header Generation Tool – javah (JEP 313)
This is a housekeeping change to remove javah tool from JDK. The tool functionality is added in javac as part of JDK 8, which provides ability to write native header files at the compile-time rendering javah useless.
Consolidate the JDK Forest into a Single Repository (JEP 296)
Over the years there have been various Mercurial repositories in for JDK codebase. Different repositories do provide some advantage, but they also had various operational downsides. As part of this change, numerous repositories of the JDK forest are combined into a single repository in order to simplify and streamline development.
API Changes – Java 10 Features
Java 10 has added and removed (Yes It’s not a Typo) API’s. Java 9 introduced enhanced deprecation where certain API’s were marked to be removed in future releases. API’s Removed: You can find the API’s removed here. API’s Added: 73 new API’s was added in Java 10. You can find the API’s added along with comparison here. Let’s go through a few additions:
- List, Map & Set Interfaces are added with a static copyOf(Collection) method. Its returns an unmodifiable List, Map or Set containing the entries provided. For a List, if the given List is subsequently modified, the returned List will not reflect such modifications.
- Optional & its primitive variations get a method orElseThrow(). This is exactly same as get(), however the java doc states that it is a preferred alternative then get()
- Collectors class gets various methods for collecting unmodifiable collections (Set, List, Map)
List actors = new ArrayList<>(); actors.add("Jack Nicholson"); actors.add("Marlon Brando"); System.out.println(actors); // prints [Jack Nicholson, Marlon Brando] // New API added - Creates an UnModifiable List from a List. List copyOfActors = List.copyOf(actors); System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando] // copyOfActors.add("Robert De Niro"); Will generate an // UnsupportedOperationException actors.add("Robert De Niro"); System.out.println(actors); // prints [Jack Nicholson, Marlon Brando, Robert De Niro] System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando] String str = ""; Optional name = Optional.ofNullable(str); // New API added - is preferred option then get() method name.orElseThrow(); // same as name.get() // New API added - Collectors.toUnmodifiableList List collect = actors.stream().collect(Collectors.toUnmodifiableList()); // collect.add("Tom Hanks"); // Will generate an // UnsupportedOperationException
Conclusion- Java 10 Features
In this article, we went through the different new feature addition of Java 10. Overview