New Features in Java 16

Rajesh kumar
9 min readMar 15, 2021

With the General Availability of Java 16 tomorrow (i.e) Mar 16th, 2021, we have some new changes that are coming with Java 16. Let’s start with the Java 16 release schedule and then explore each of the Changes at a high level.

Release Schedule:

2020/12/10 -Ramp down Phase One (fork from main line)
2021/01/14 -Ramp down Phase Two
2021/02/04 -Initial Release Candidate
2021/02/18 -Final Release Candidate
2021/03/16 -General Availability

New Features in Java 16:

1) Sealed Classes (Second Preview) -JEP 397
2) Records -JEP 395
3) Warnings for Value-Based Classes -JEP 390
4) Pattern Matching for instanceof -JEP 394
5) Packaging Tool -JEP 392
6) Strongly Encapsulate JDK Internals by Default -JEP 396
7) Enable C++14 Language Features -JEP 347
8) Migrate from Mercurial to Git -JEP 357
9) Migrate to GitHub -JEP 369
10) ZGC: Concurrent Thread-Stack Processing -JEP 376
11) Unix-Domain Socket Channels -JEP 380
12) Alpine Linux Port -JEP 386
13) Elastic Metaspace -JEP 387
14) Windows/AArch64 Port -JEP 388
15) Foreign Linker API (Incubator) -JEP 389
16) Foreign-Memory Access API (Third Incubator) -JEP 393
17) Vector API (Incubator) — JEP 338

1) Sealed Classes (Second Preview):
Sealed Classes was firstly introduced with jdk 15 as initial preview feature. This feature helps every java developer in the way we can restrict/access the class data in the hierarchy. Sealed classes and interfaces restrict on which other classes or interfaces may extend or implement them. With jdk 16 we have a few enhancements to sealed classes.

->Specifying the notion of a contextual keyword, superseding the prior notions of restricted identifier and restricted keyword in the JLS. Introduce the character sequences sealed, non-sealed, and permits as contextual keywords.
->As with anonymous classes and lambda expressions, local classes may not be subclasses of sealed classes when determining the implicitly declared permitted subclasses of a sealed class or sealed interface.
->Enhance narrowing reference conversion to perform stricter checking of cast conversions with respect to sealed type hierarchies.

For a more detailed explanation of Sealed Classes refer to jdk 15

2) Records:

Records are a new kind of type declaration in the Java language. Like an enum, a record is a restricted form of class. Records avoid the generation of boilerplate code for repetitive tasks (such as constructor, toString, hashcode, getter methods) of class attributes. Records were introduced with jdk 14 as the initial preview feature with jdk 15 we have now a second preview which brings us with some enhancements/changes to the compiler, JLS, and JVM. Now with jdk 16 we have below refinement done to records

->Relaxing the longstanding restriction whereby an inner class cannot declare a member that is explicitly or implicitly static. This will become legal and, in particular, will allow an inner class to declare a member that is a record class.

For a more detailed explanation of Records refer to jdk 14

3) Warnings for Value-Based Classes:

With the jdk 16 there is a change to primitive wrapper classes(ava.lang.Integer, java.lang.Double, etc..) as value-based and deprecate their constructors for removal, prompting new deprecation warnings. Provide warnings about improper attempts to synchronize on instances of any value-based classes in the Java Platform. The Valhalla Project is pursuing a significant enhancement to the Java programming model in the form of primitive classes. Such classes declare their instances to be identity-free and capable of inline or flattened representations, where instances can be copied freely between memory locations and encoded using solely the values of the instances’ fields.

Clients of the value-based classes will generally be unaffected by primitive class migration, except where they violate recommendations for usage of these classes. In particular, when running on a future Java release in which the migration has occurred:
->Instances of these classes that are equal (per equals) may also be considered identical (per ==), potentially breaking programs that rely on a != result for correct behavior.
->Attempts to create wrapper class instances with new Integer, new Double, etc., rather than implicit boxing or calls to the valueOf factory methods, will produce LinkageErrors.
->Attempts to synchronize on instances of these classes will produce exceptions.

4) Pattern Matching for instanceof:

In jdk 16 pattern matching for instancof became available as a feature. Pattern matching for instanceof was proposed by JEP 305 and delivered in jdk 14 as a preview feature. It was re-proposed by JEP 375 and delivered in jdk 15 for the second round of preview now it became a feature no more preview feature. with jdk 16 few new changes are below

->Lift the restriction that pattern variables are implicitly final, to reduce asymmetries between local variables and pattern variables.
->Make it a compile-time error for a pattern instanceof expression to compare an expression of type S against a pattern of type T, where S is a subtype of T. (This instanceof expression will always succeed and is then pointless. The opposite case, where a pattern match will always fail, is already a compile-time error.)

For a more detailed explanation of Pattern Matching for instanceof refer to jdk 14

5) Packaging Tool :

The packaging Tool was firstly introduced in jdk 14 incubating tool. The main motivation of having packaging tool is to have Java applications packaged like installers according to the platform, for windows its.exe where the java application can be installed by just double-clicking on the installer, it gives end users a natural installation experience. Now with jdk 16, it’s no more an incubatory tool but available as a feature. with jdk 16 below are 2 changes for the tool that developer need to note
-> The tool is no more available in the incubator module so change from jdk.incubator.jpackage to jdk.jpackage
-> There is a change with the options — bind-services is replaced with — jlink-options .

For a more detailed explanation of Packaging Tool refer to jdk 14

6) Strongly Encapsulate JDK Internals by Default:

This is an internal jdk change to Strongly encapsulate all internal elements of the JDK by default, except for critical internal APIs such as sun.misc.Unsafe. Allow end users to choose the relaxed strong encapsulation that has been the default since JDK 9. sun.misc.unsafe is still available in jdk 16 where a large number of tools, libraries, and framework still depend on this package which is not allowed to remove. But from Java 9, there was an improvement in both the security and the maintainability of the JDK by leveraging modules to limit access to its internal elements. Modules provide strong encapsulation.

7) Enable C++14 Language Features:

The purpose of this JEP is to formally allow C++ source code changes within the JDK to take advantage of C++14 language features and to give specific guidance about which of those features may be used in HotSpot code. This allows the use of C++14 language features in JDK C++ source code and gives specific guidance about which of those features may be used in HotSpot code.

8,9) Migrate from Mercurial to Git on GitHub:

This is an internal change from the Jdk community to Migrate the OpenJDK Community’s source code repositories from Mercurial (hg) to Git. The jdk code maintenance in the Mercurial has been for a long time and the time has come to move to Git which is the current best code repository in the industry and the Jdk community has decided to move to GitHub.

10) ZGC: Concurrent Thread-Stack Processing:

ZGC Garbage Collector was firstly introduced with jdk 11 JEP 333 as an Experimental feature and over the period with jdk13,14,15 we had seen continuous improvements with this Garbage collector. with Jdk 16 we have one more new improvement coming where Move ZGC thread-stack processing from safepoints to a concurrent phase. with this
->Remove thread-stack processing from ZGC safepoints.
->Make stack processing lazy, cooperative, concurrent, and incremental.
->Remove all other per-thread root processing from ZGC safepoints.
->Provide a mechanism by which other HotSpot subsystems can lazily process stacks

11) Unix-Domain Socket Channels:

Unix-domain sockets are used for inter-process communication (IPC) on the same host. They are similar to TCP/IP sockets in most respects, except that they are addressed by filesystem pathnames rather than Internet Protocol (IP) addresses and port numbers. The goal of this JEP is to support all of the features of Unix-domain sockets that are common across the major Unix platforms and Windows. Unix-domain socket channels will behave the same as existing TCP/IP channels in terms of read/write behavior, connection setup, acceptance of incoming connections by servers, multiplexing with other non-blocking selectable channels in a selector, and support of relevant socket options.

12) Alpine Linux Port:

Port the JDK to Alpine Linux, and to other Linux distributions that use musl as their primary C library, on both the x64 and AArch64 architectures.Musl is an implementation for Linux-based systems, Several Linux distributions including Alpine Linux and OpenWrt are based on musl .Alpine Linux distribution is widely adopted in cloud deployments, microservices, and container environments due to its small image size. A Docker base image for Alpine Linux, for example, is less than 6 MB. Enabling Java to run out-of-the-box in such settings will allow Tomcat, Jetty, Spring, and other popular frameworks to work in such environments natively.

By using jlink (JEP 282) to reduce the size of the Java runtime, a user will be able to create an even smaller image targeted to run a specific application. The set of modules required by an application can be determined via the jdeps command. For example, if a target application depends only on the java.base module then a Docker image with Alpine Linux and a Java runtime with just that module and the server VM fits in 38 MB.

13) Elastic Metaspace :

This is an internal change in the jdk hotspot. with the new change Return unused HotSpot class-metadata (i.e., metaspace) memory to the operating system more promptly, reduce metaspace footprint and simplify the metaspace code in order to reduce maintenance costs.

14) Windows/AArch64 Port:

This is also an internal change in the jdk to port jdk on Windows/AArch64. With the release of new consumer and server-class AArch64 (ARM64) hardware, Windows/AArch64 has become an important platform due to end-user demand.

15) Foreign Linker API (Incubator):

Java has supported native method calls via the Java Native Interface (JNI) since Java 1.1, but this path has always been hard and brittle. Wrapping a native function with JNI requires developing multiple artifacts: a Java API, a C header file, and a C implementation. Even with tooling help, Java developers must work across multiple toolchains to keep multiple platform-dependent artifacts in sync. This is hard enough with stable APIs, but when trying to track APIs in progress, it is a significant maintenance burden to update all of these artifacts each time the API evolves. Finally, JNI is largely about code, but code always exchanges data, and JNI offers little help in accessing native data. For this reason, developers often resort to workarounds (such as direct buffers or sun.misc.Unsafe) which make the application code harder to maintain or even less safe.

With jdk 16 with this JEP Introduces an API that offers statically-typed, pure-Java access to native code. This API, together with the Foreign-Memory API (JEP 393), will considerably simplify the otherwise error-prone process of binding to a native library. The Foreign-Memory Access API, which provides the foundations for this JEP, was first proposed by JEP 370 and targeted to Java 14 in late 2019 as an incubating API, and then subsequently refreshed by JEP 383 and JEP 393, which were targeted to Java 15 and 16, respectively. Together, the Foreign-Memory Access API and the Foreign Linker API constitute key deliverables of Project Panama.

15) Foreign-Memory Access API (Third Incubator):

Foreign-Memory Access API was firstly introduced in jdk 14. This API will allow Java programs to safely and efficiently access foreign memory outside of the Java heap. with jdk 16 below are some of the changes made
->A clearer separation of roles between the MemorySegment and MemoryAddress interfaces;
->A new interface, MemoryAccess, which provides common static memory accessors to minimize the need for the VarHandle API in simple cases;
->Support for shared segments; and
->The ability to register segments with a Cleaner.

For a more detailed explanation of Foreign-Memory Access API refer to jdk 14

16) Vector API (Incubator):

With Jdk 16 this is a new feature in the Incubator module in jdk.incubator.vector, to express vector computations that reliably compile at runtime to optimal vector hardware instructions on supported CPU architectures and thus achieve superior performance to equivalent scalar computations. The API shall be capable of clearly and concisely expressing a wide range of vector computations consisting of a sequence of vector operations often composed within loops and possibly with control flow. It should be possible to express a computation that is generic to vector size (or the number of lanes per vector) thus enabling such computations to be portable across hardware supporting different vector sizes.

Download Open jdk 16 @ https://jdk.java.net/16/

--

--