What’s new in Java 15

java 15

Introduction

Java 15 is here! The time has come for the most recent version of this amazing programming language. Below you may find what’s new in Java 15, the list of features as well as explanation of each one along with examples to make the concepts more easily understandable.

Each Java version may include features that may not be finished like a preview or incubator. Here is an explanation of these statuses :

A preview feature is a feature that is designed, specified and implemented but not permanent.

An incubator feature is an experimental one under the package jdk.incubator to allow users to provide their feedback.

Second preview means that the functionality:

  • was previewed in the previous version
  • incorporates some improvements
  • re-previewed to get more user feedback.

Previews/ Incubator

Sealed Classes (Preview)

Enhance the Java programming language with sealed classes and interfaces. Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them.

A sealed class cannot be extended or implemented except if :

  • declared explicitly using the sealed keyword at the class level
  • using the keyword permits for authorized classes

In the example below we declare that the class Shape permits three specific sub-classes.

package com.example.geometry;

public sealed class Shape
    permits Circle, Rectangle, Square {...}

Pattern Matching for instanceof (Second Preview)

Enhance the Java programming language with pattern matching for the instanceof operator. Pattern matching allows common logic in a program, namely the conditional extraction of components from objects, to be expressed more concisely and safely.

The goal of this feature is to get rid of boilerplate code.

Often we have to do something similar to this :

if (obj instanceof Integer) {
    Integer i = (Integer) obj;
    // do something with i as Integer
} else {
    Object obj = obj;
    //do something with obj as an Object
}

This is prone to errors and kind of repetitive. There are several integer declarations here. Instead of this, with this feature we can do the following :

if (obj instanceof Integer i) {
    // do something with i 
} else {
    // cannot use i here
}

Future work on this JEP will include the same logic for other statements like the switch statement.

Read more about pattern matching here.

Records (Second Preview)

Situation before this functionality

final class Person{
    public final String firstname;
    public final String lastname;

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    // here we need to implement equals, hashCode, toString
    // which is considered "boilerplate" code

The getters and setters method is used a lot in Java. It applies the principle of encapsulation, a basic principle in object oriented programming.

Even if this principle is used a lot, it is boilerplate code which wastes the time of the developer. Fortunately the IDEs help with this kind of code by generating it instead of letting you write it.

Lombok : a useful library

Lombok is a library which helps us solve this problem. Let’s see an example together:

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor(access = AccessLevel.PUBLIC)
    public class Person {
    public final String firstname;
    public final String lastname;
}

The issue here is that Lombok is an external library. We need to get the dependency and install it.

Link to Lombok is here.

The new solution

Records are classes that act as transparent carriers for immutable data. Records can be thought of as nominal tuples.

The goal of the records is to be able to do the following :

record Person(String firstname, String lastname) { }

This is a clear and compact syntax.

With this functionality we can more easily write a POJO (Plain Old Java Object) using a record. We no longer need to implement the basic equals () and hashCode () methods.

The records feature can optionally replace the Lombok library.

Read more about records here.

Foreign-Memory Access API (Second Incubator)

Introduce an API to allow Java programs to safely and efficiently access foreign memory outside of the Java heap. The main goal is to avoid the cost and unpredictability associated with garbage collection (especially when maintaining large caches). Another goal is to share memory across multiple processes. This feature introduces three main abstractions: MemorySegmentMemoryAddress, and MemoryLayout.

  • MemorySegment is a segment of contiguous memory
  • MemoryAddress models an address
  • MemoryLayout is a description of a segment’s content

Here is an example of a MemorySegment associated with a native memory buffer of 100 bytes

try (MemorySegment segment = MemorySegment.allocateNative(100)) {
   ...
}

Independent features

Edwards-Curve Digital Signature Algorithm (EdDSA)

In public key cryptography, Edwards-Curve Digital Signature Algorithm is a mathematical scheme for verifying the authenticity of digital messages. This feature implements cryptographic signatures using the Edwards-Curve Digital Signature Algorithm (EdDSA) as described by RFC 8032.

// example: generate a key pair and sign
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
// algorithm is pure Ed25519
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(kp.getPrivate());
sig.update(msg);
byte[] s = sig.sign();

// example: use KeyFactory to construct a public key
KeyFactory kf = KeyFactory.getInstance("EdDSA");
boolean xOdd = ...
BigInteger y = ...
NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519");
EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y));
PublicKey pubKey = kf.generatePublic(pubSpec);

Hidden Classes

Introduce hidden classes, which are classes that cannot be used directly by the bytecode of other classes. Hidden classes are intended for use by frameworks that generate classes at run time and use them indirectly, via reflection.

The most important difference is in the creation of a hidden class. To create a normal class we invoke ClassLoader :: defineClass. On the other hand, a hidden class is created by the invocation of Lookup :: defineHiddenClass. This causes the JVM to derive the hidden class from the provided bytes, bind the hidden class, and return a lookup object that provides reflection access to the hidden class.

A hidden class may be defined as a member of an access control nest, and may be unloaded independently of other classes.

Access control nest.

Text Blocks

A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired.

This JDK adds blocks of text to the Java language. A block of text is a multiline string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired.

In Java, embedding an HTML, SQL, XML, or JSON snippet in a string literal often requires significant editing with escape and concatenation before it can be compiled.

Text Blocks provide a simpler approach to this problem described below :

Using "one-dimension" string

String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hey ho my friends!</p>\n" +
              "    </body>\n" +
              "</html>\n";
Using a "two-dimension" text block : 

String html = """
              <html>
                  <body>
                     <p>Hey ho my friends!</p>
                  </body>
              </html>
              """;

Deprecated – Reimplementation

Remove the Nashorn JavaScript Engine

Remove the Nashorn JavaScript script engine and APIs, and the jjs tool. The engine, the APIs, and the tool were deprecated for removal in Java 11 with the express intent to remove them in a future release. The reason was that the team considered it hard to maintain.

Remove the Solaris and SPARC Ports

Remove the source code and build support for the Solaris/SPARC, Solaris/x64, and Linux/SPARC ports. These ports were deprecated for removal in JDK 14 with the express intent to remove them in a future release.

Deprecate RMI Activation for Removal

Deprecate the RMI Activation mechanism for future removal. RMI Activation is an obsolete part of RMI that has been optional since Java 8. No other part of RMI will be deprecated.

Reimplement the Legacy DatagramSocket API

Replace the underlying implementations of the java.net.DatagramSocket and java.net.MulticastSocket APIs with simpler and more modern implementations that are easy to maintain and debug. The new implementations will be easy to adapt to work with virtual threads, currently being explored in Project Loom. This is a follow-on to JEP 353, which already reimplemented the legacy Socket API.

Disable and Deprecate Biased Locking

Disable biased locking by default, and deprecate all related command-line options. The performance gains seen in the past are far less evident today. This fact combined with the difficulty to maintain it led to this decision.

2 New Garbage Collectors

Garbage collector is an automatic memory manager which frees up memory by removing objects that are not needed anymore.

ZGC: A Scalable Low-Latency Garbage Collector

The ZGC project actually started with Java 11. It is a complex subject which needed to be introduced gradually to allow users to provide their feedback and have bugs fixed. In Java 15 this feature is considered complete and ready to be used in production mode.

ZGC may be activated using the -XX:+UnlockExperimentalVMOptions -XX:+UseZGC command-line options.

This feature offers this now garbage collector but does not change the default one which remains G1.

Shenandoah: A Low-Pause-Time Garbage Collector

Similar to ZGC here Shenandoah is a garbage collector that is production ready. It was introduced as experimental in Java 12.

It may be activated with XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC options.

  • This feature keeps the default garbage collector G1.
Java 15

Useful Links

JDK 15 build is here.

Check the OpenJDK official page.

About the preview features.

About the incubator modules.

Conclusion

Java 15 has several new features to offer, as any release. This release adds more value to java due to :

  • Removal or set as obsolete of old libraries and replacing them with modern ones
  • Two new garbage collectors
  • New useful features (hidden classes, text blocks, records)

It is always worth updating the version.

This was the article about what’s new in java 15. If you want to read more java or development related articles, check the articles page of this website here.

Leave a Comment