In this tutorial we’ll learn about the Features of Java15 and how is it different from the previous versions.

Introduction

Java 15 and its Java Development Kit 15 open source has been released on 15th September 2020, the most common coding language and application platform used in the world.

JDK 15 is a short term release, only to be supported by Oracle Premier Support which is basically a non LTS version. There are a few additions and few are removed/disabled from current java eco-system.

Features of Java15 Added

Here is the list of the new features added:

1.JEP 339 – Edwards-Curve Digital Signature Algorithm:

EdDSA is a modern elliptic curve scheme with advantages over existing signature schemes in the JDK. The main reason to include this feature in Java 15 is that it is a popular signature algorithm due to its security and performance compared to similar signatures ECDSA.
Here is a code for Key Pair and sign:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519"); 
   KeyPair kp = kpg.generateKeyPair();
   Signature sig = Signature.getInstance("Ed25519");  
   sig.initSign(kp.getPrivate());
   sig.update(msg); 
   byte[] s = sig.sign();

More about JEP 339

2. JEP 360 – Sealed Classes(Preview):

Sealed classes have been there in Kotlin for a while and Java 15 finally introduces this feature for better control over inheritance. As the name suggests, Sealed classes let you restrict or permit class hierarchies to only certain types. Let’s make it clear by the example given below which shows Animal class which specifies three permitted subclasses:

package com.onlinetutorialspoint;
public sealed class Fruits
permits Apple, Banana, Mango {...}

Every permitted class must be set with an explicit modifier. It can either be final or sealed or non-sealed. Before Java 15, developers could only use final keyword or scope modifiers to control inheritance. So, sealed classes bring the added flexibility for Java developers when defining class hierarchies.

More about JEP 360 Sealed classes

3. JEP 371 – Hidden Classes:

Hidden Classes which are invisible to JVM but can be loaded from their bytecode dynamically and then they can be used by their reference i.e by java reflection. They can not be used directly by the bytecode of other classes. The important difference in how a hidden class is created is the name it gets on creation. A hidden class is not anonymous. Name of the class can be fetched via Class::getName and the name has a sufficiently unusual form that it effectively makes the class invisible to all other classes.
Example for creating a hidden class

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Base64;
​
public class Test {
   static final String testString = "ABC";
   public static void main(String[] args) throws Throwable {
       byte[] testStringInBytes = Base64.getDecoder().decode(testString);
​
       Class<?> proxy = MethodHandles.lookup()
               .defineHiddenClass(testStringInBytes,
                       true, MethodHandles.Lookup.ClassOption.NESTMATE)
               .lookupClass();
       System.out.println(proxy.getName());
   }
}

More about JEP-371

4. JEP 375 – Pattern Matching for instanceof:

Pattern matching for instanceof was first a preview feature in Java 14. This JEP is a second preview of the pattern matching to gain additional feedback, with no change to the API.
Pattern matching allows common logic in a program, chiefly the conditional extraction of components from objects, to be expressed more easily and concisely.

Before the feature was included:

if (obj instanceof String) {
   String str = (String) obj; // need to declare and cast again the object
   .. str.contains(..) ..
}else{
    str = ....
}

After the feature was included:

if (!(obj instanceof String str)) {
   .. str.contains(..) .. // no need to declare str object again with casting
} else {
   .. str....
}

More about JEP-375

5. JEP 378 – Text Blocks:

This Previewed in both JDK 14 and JDK 13, are intended to simplify the task of writing Java programs by making it easy to express strings that span several lines of source code, while avoiding escape sequences in common cases.This will allow adding text blocks to the Java language. A text block is a multi-line string literal that avoids the necessity of escape sequences and automatically formats the string in a predictable way. Not only that but also the addition of new methods to string to support text blocks

String::stripIndent(): used to strip away incidental white space from the text block content
String::translateEscapes(): used to translate escape sequences
String::formatted(Object… args): simplify value substitution in the text block

Learn more about text blocks here

More about JEP-378

Example:

<pre><code class="language-java">

String html = "<html>\n" +
               "  <body>\n" +
               "     <p>Hello, World</p>\n" +
               "  </body>\n" +
               "</html>\n";

 String java15 = """
                 <html>
                     <body>
                         <p>Hello, World</p>
                     </body>
                 </html>
                 """;
</code></pre>

6. JEP 384 – Records:

This is the second preview of Records which were launched as JEP 359 in Java 14 as a preview feature. This JEP enhanced the records with features like support sealed types, local records, annotation on records, and Reflection APIs for records.

Goals of the plan include devising an object-oriented construct that expresses a simple aggregation of values, helping programmers focus on modeling immutable data rather than extensible behavior, automatically implementing data-driven methods such as equals and assessors, and preserving longstanding Java principles such as nominal typing and migration compatibility.
Records and Sealed Types:

public int hashCode() {
    return Objects.hash(message, dimensionl);
  }
​
  @Override
  public String toString() {
    return "Message{" +
        "message='" + message + '\'' +
        ", dimensionl=" + dimensionl +
        '}';
  }
}

More about JEP-384

7. JEP 385 – Deprecate RMI activation for removal:

This is an obsolete part of remote method invocation (RMI) that has been optional since JDK 8. RMI Activation was made optional in Java 8 and removed in Java 15. RMI Activation imposes an ongoing maintenance burden. No other part of RMI will be deprecated.

Lazy instantiation of resources is handled by load balancers, orchestration, and containers. None of these mechanisms is present in the RMI Activation model for distributed systems and Java team found no evidence of any new applications being written to use RMI Activation.

More about JEP-385

8. JEP 372 – Removal of Nashorn Javascript:

It was debuted in JDK 8 in March 2014, but has since been made obsolete. This is removal from the Java and it should not affect the way javax.scriptAPI. This JEP also removed the below two modules:

jdk.scripting.nashorn – contains the jdk.nashorn.api.scripting and jdk.nashorn.api.tree packages.
jdk.scripting.nashorn.shell – contains the jjs tool.

More about JEP-372

9. JEP 383 – Foreign-Memory Access API:

It would let Java programs safely and efficiently access foreign memory outside of the Java heap. Many Java programs access foreign memory, such as Ignite, mapDB, memcached, Lucene, and Netty’s ByteBuf API. Java 14 JEP 370 introduced a new Foreign-Memory Access API as an Incubator Modules. This JEP made some changes to the APIs, and it will be still in incubator modules. The API would help avoid the cost and unpredictability associated with garbage collection, share memory across processes, and serialize and deserialize memory content by mapping files onto memory.

Example Code:

import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryHandles;
import jdk.incubator.foreign.MemorySegment;

import java.lang.invoke.VarHandle;
import java.nio.ByteOrder;

public class HelloForeignMemory {
    public static void main(String[] args) {
        VarHandle intHandle = MemoryHandles.varHandle(
            int.class, ByteOrder.nativeOrder());
        try (MemorySegment segment = MemorySegment.allocateNative(1024)) {
            MemoryAddress base = segment.baseAddress();
            // print memory address
            System.out.println(base);                 
            // set value 999 into the foreign memory
            intHandle.set(base, 999);                 
            // get the value from foreign memory
            System.out.println(intHandle.get(base));  
        }
    }
}

We need to add --add-modules jdk.incubator.foreign to enable the incubator modules jdk.incubator.foreign

More about JEP-383

10. JEP 381 – Removal of the Solaris and SPARC Ports:

Support for Solaris on SPARC and x64 and Linux on SPARC is removed. As new features being developed, like Valhalla and Loom, require complex processor-specific code. Removing these ports will make implementation and maintenance of these features simpler. Both Solaris and SPARC have been superseded in recent years by the Linux OS and Intel processors.

More about JEP-381

11. JEP 379 – Shenandoah:

A Low-Pause-Time Garbage Collector: Shenandoah GC is an experimental feature since Java 12, now it becomes a product feature. Before Java 15, we need –XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC to enable the Shenandoah GC.
In Java 15, we only need -XX:+UseShenandoahGC to enable the Shenandoah GC.

More about JEP-379

12. JEP 377 – ZGC:

A Scalable Low-Latency Garbage Collector: ZGC is an experimental feature since Java 11, now it becomes a product feature. This JEP fixed some bugs, added some features and enhancements, and now supported major platforms like Linux/x86_64, Linux/aarch64, Windows, and macOS.
This JEP also changes the Z Garbage Collector from an experimental feature into a product feature. However, the default garbage collector remains G1.

Some features added are:

  • Minimum heap size decreased to 8MB
  • Concurrent class unloading
  • Maximum heap size increased from 4TB to 16TB
  • Support for the JFR leak profiler
  • Support for class-data sharing
  • Limited and discontiguous address spaces
  • Support for placing the heap on NVRAM
  • Platforms supported include Linux, Windows, and MacOS.

More about JEP-377

13. JEP 374 – Disable and Deprecate Biased Locking:

Because the benefits of Biased Locking is becoming less important with modern computers, it will be disabled by default and deprecated. It can be enabled by using -XX:+UseBiasedLocking. The older or legacy Java application uses synchronize collections APIs like Hashtable and Vector, and the biased locking may giving performance gains. Nowadays, the newer Java application generally uses the non-synchronized collections HashMap and ArrayList, and the performance gains of biased locking are generally less useful now. Biased locking uses complex code that is costly to maintain.

More about JEP-374

14. JEP-373 Reimplement the Legacy DatagramSocket API:

It is done by replacing the underlying implementations of the java.net.datagram.Socket and java.net.MulticastSocket APIs with simpler and more modern implementations. The current implementations of java.net.datagram.Socket and java.net.MulticastSocket date back to JDK 1.0 and a time when IPv6 was still under development.
The new implementation will be default and the old implementation can be used by using jdk.net.usePlainDatagramSocketImpl property.

More about JEP-373

Conclusion

So these were the major language features in Java 15 which helped developers and programmers in building applications and programs.

References

Happy Learning 🙂