Home  >  Core Java

Java 16 New Features

By Arvind Rai, July 11, 2021
On this page we will discuss new features and enhancements introduced in Java 16.

Record Classes (JEP 384)

The record class was introduced in Java 14 as preview feature. In Java 16, the record classes are adopted as permanent language feature. The record is a kind of type declaration like enum. It is used for "plain data carriers" classes that contain data not meant to be altered and only the most fundamental methods such as constructors and accessors. The record classes can also be created as local record within a method, same as local classes.
package com.concretepage;

record Rectangle(int length, int width) { }

public class MyApp {
  public static void main(String[] args) {
	Rectangle rec = new Rectangle(12, 5);
	System.out.println(rec.length()); //12
	System.out.println(rec.width()); //5
	//local record class
	record Employee(String name, int age) { }
	Employee emp = new Employee("Mahesh", 22);
	System.out.println(emp.name); //Mahesh
	System.out.println(emp.age); //22

Pattern Matching for instanceof Operator (JEP 361)

The instanceof operator has been changed for pattern matching of an object to make code more concise and robust. This feature was introduced in Java 14 as preview feature. In Java 16, this feature has been adopted as permanent language feature. Look at the below code.
if (animal instanceof Cow) {
  Cow a = (Cow) animal;
Now with new instanceof, we can write above code as following.
if (animal instanceof Cow a) {
Find the sample example.
package com.concretepage;

interface Animal {
class Cow implements Animal {
  String name;

  public Cow(String name) {
	this.name = name;

  public String getCowName() {
	return name;
class Horse implements Animal {
  String name;

  public Horse(String name) {
	this.name = name;

  public String getHorseName() {
	return name;
public class MyApp {
  public static void main(String[] args) {
	Animal ob = new Cow("Cow");
  static String getName(Animal animal) {
	if (animal instanceof Cow a) {
	} else if (animal instanceof Horse a) {
	return null;

Sealed Classes (JEP 360)

Sealed classes and interfaces were introduced in Java 15 as preview feature. In Java 16 they are previewed again. A sealed class is a class that can be inherited by only specified classes. Look into the below code.
public sealed class Animal
               permits Cow, Lion {
A sealed class is created using sealed keyword. The above sealed class Animal can only be extended by Cow and Lion classes.
public class Cow implements Animal {
public class Lion implements Animal {

Day Period Support Added to java.time Formats (JDK-8247781)

A new formatter pattern, letter 'B' has been added to translate day period in below classes.
If the local time is morning time, the output will be as 'in the morning'.
String time = DateTimeFormatter.ofPattern("B").format(LocalTime.now());
Suppose current time is 11:50 PM, then output will be 'at night'.

Stream.toList() Method Added (JDK-8180352)

In Java 16, a new default method toList() is added to Stream interface as following.
default List<T> toList() 
The Stream::toList accumulates the elements of this stream into a List. Find the example.
Stream<String> stream = Stream.of("A", "B", "C");
List<String> strList = stream.toList();
System.out.println(strList.size()); // 3

IntStream intStream = IntStream.of(10, 12, 15, 20);
List<Integer> intList = intStream.boxed().toList();
System.out.println(intList.size()); // 4 
The Stream::toList is the replacement of using Collectors.toList() to convert stream into list.
List<String> strList = stream.collect(Collectors.toList());
List<Integer> intList = intStream.boxed().collect(Collectors.toList()); 

Packaging Tool (JEP 392)

Java 14 provided jpackage as incubating tool for packaging self-contained Java applications. It remained an incubating tool in Java 15. Now in Java 16, it is promoted from incubation to a production-ready feature and hence the jdk.incubator.jpackage is changed to jdk.jpackage package.

Other New Features and Enhancements

1. JEP 389 -Foreign Linker API (Incubator) : Introduce an API that offers statically-typed, pure-Java access to native code.
2. JEP 396: Strongly encapsulate all internal elements of the JDK by default, except for critical internal APIs such as sun.misc.Unsafe.
3. JEP 393 - Foreign-Memory Access API (Third Incubator): Introduce an API to allow Java programs to safely and efficiently access foreign memory outside of the Java heap.
4. JEP 390: Users of the value-based classes provided by the standard libraries should avoid relying on the identity of class instances. Programmers are strongly discouraged from calling the wrapper class constructors, which are now deprecated for removal.
5. JDK-8159746: A new method, invokeDefault, has been added to the java.lang.reflect.InvocationHandler interface to allow a default method defined in a proxy interface to be invoked.
6. JEP 380 - Unix domain sockets: Provides support for Unix domain sockets (AF_UNIX) in the java.nio.channels, SocketChannel, and ServerSocketChannel classes.
7. JEP 338 - Vector API (Incubator): Provides an initial iteration of an incubator module, 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.
8. Now CompileCommand flag has an option type that has been used for a collection of sub commands.
9. JEP 376: The Z Garbage Collector now processes thread stacks concurrently.
10. JDK-8236926 - Concurrently Uncommit Memory in G1: This new feature is always enabled and changes the time when G1 returns Java heap memory to the operating system.
11. JDK-8257602: A new JFR event, jdk.ObjectAllocationSample, is introduced to allow always-on, low-overhead allocation profiling.
12. JEP 387 "Elastic Metaspace" overhauls the VM-internal metaspace- and class-space-implementation.
13. JDK-8242068: This enhancement includes two main changes: (a) The JarSigner API and the jarsigner tool now support signing a JAR file with an RSASSA-PSS or EdDSA key. (b) Instead of signing the .SF file directly, jarsigner creates a SignerInfo signedAttributes field which contains ContentType, MessageDigest, SigningTime, and CMSAlgorithmProtection.
14. JDK-8172366: SUN, SunRsaSign, and SunEC provider have been enhanced to support SHA-3 based signature algorithms.
15. JDK-8218021: When signing a file that contains POSIX file permission or symlink attributes, jarsigner now preserves these attributes in the newly signed file but warns that these attributes are unsigned and not protected by the signature.
16. JDK-8244148: The -trustcacerts and -keystore options have been added to the -printcert and -printcrl commands of the keytool utility.
17. JDK-8242332: The SunPKCS11 provider has been updated with SHA-3 algorithm support. Additional KeyGenerator support for Hmac using message digests other than SHA-3 has also been added.
18. JDK-8254631: Certain TLS ALPN values couldn't be properly read or written by the SunJSSE provider.
19. JDK-8166596: The SunJSSE provider now supports the use of the EdDSA signature algorithm.


JDK 16 Release Notes
Java Language Updates

©2021 concretepage.com | Privacy Policy | Contact Us