Java 15 : what’s new ?
Now that Java 15 is features complete (Rampdown Phase One at the day of writing), it’s time to walk throught all it’s functionalities that brings to us, developers, this new version.
This article is part of a series on what’s new on the last versions of Java, for those who wants to read the others, here are the links : Java 14, Java 13, Java 12, Java 11, Java 10, and Java 9.
This new version brings lots of new JEPs, the main one being the addition of Sealed Classes. Records and Pattern Matching introduced in Java 14 remain in preview in this version.
JEP 360 : Sealed Classes
Sealed Classes allow you to limit the number of implementations of a class or an interface to a predefined list. The hierarchy of this class / interface is therefore closed (sealed).
As this hierarchy is known at compile time, this opens up possibilities for Pattern Matching, a future implementation of switch based on the type of an object is planned in one of the next versions of Java. This also allows the author of a class / interface to express its use in a finer way than via visibility modifiers by restricting its use to a specific list.
Here are some examples taken from the JEP
package com.example.geometry;
public sealed class Shape
permits Circle, Rectangle, Square {...}
If classes are declared in the same source file, the permits
clause can be ignored.
package com.example.geometry;
sealed class Shape {...}
class Circle extends Shape {...}
class Rectangle extends Shape {...}
class Square extends Shape {...}
Now that we know the list of classes implementing an interface, we can more easily write a series of if/else on the Shape
class:
Shape rotate(Shape shape, double angle) {
if (shape instanceof Circle) return shape;
else if (shape instanceof Rectangle) return shape.rotate(angle);
else if (shape instanceof Square) return shape.rotate(angle);
}
When Pattern Matching would have been extended to cover Sealed Classes, we could write a switch with a test on the type of an object:
Shape rotate(Shape shape, double angle) {
return switch (shape) {// won't compile in Java 15 ...
case Circle c -> c; // no action needed
case Rectangle r -> r.rotate(angle);
case Square s -> s.rotate(angle);
}
}
A new keyword has been introduced non-sealed
which opens the hierarchy from one of the subclasses or subinterfaces of a sealed class.
Other news
- JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA). Implementation of the cryptography algorithm EdDSA.
- JEP 373: Reimplement the Legacy DatagramSocket API. After re-implementing the
java.net.Socket
andjava.net.ServerSocket
in Java 13, it’s the turn ofjava.net.DatagramSocket
andjava.net.MulticastSocket
. The motivation is the same, replacing an aging implementation that is difficult to maintain with a more recent implementation to facilitate the future implementation of the Lightweight Thread of the Loom project. - JDK-8244441: support of the
certificate_authorities
extension of TLS 1.3. - JDK-8215401:
CharSequence.isEmpty()
.
Features that go from preview to standard
The following features, which were in preview, are now standard, for details on these you can refer to my previous articles.
- JEP 377: ZGC: A Scalable Low-Latency Garbage Collector
- JEP 379: Shenandoah: A Low-Pause-Time Garbage Collector
- JEP 378: Text Blocks
- JEP 358: Helpful NullPointerExceptions. JEP 358 gave us more understandable error messages for
NullPointerException
in Java 14. To my regret, this feature was disabled by default. It is now enabled by default (via JDK -8233014) and that’s a very good news!
The features that remain in preview
The following features remain in preview.
- JEP 375: Pattern Matching for instanceof. No change in this version but the functionality remains in preview because changes are planned for the following versions of Java.
- JEP 383: Foreign-Memory Access API. Functionality improvements and refactoring
- JEP 384: Records. The implementation has been revised following the first preview, we now have the possibility of creating local Records and using Sealed Classes with Records.
Deprecated or removed features
A lot of deprecation and deletion in this release. Java has decided to remove some features that haven’t been used for a long time, or which affect its maintenance, and this is generally a good thing.
- JEP 385: Deprecate RMI Activation for Removal. It is an optional part of RMI, deprecated since Java 8 and almost no longer used. It will be deleted in a future release. The rest of RMI remains supported.
- JEP 381: Remove the Solaris and SPARC Ports. A page of history of the acquisition of Sun by Oracle ends. During this takeover Oracle also bought an OS (Solaris) and a CPU architecture (SPARC). These are no longer supported by Java and their implementation in the JVM (port) is removed.
- JEP 374: Disable and Deprecate Biased Locking. Bias locking is a technique for optimizing locks that are used by a single thread. It would no longer be as relevant these days with modern CPU architectures, and entail a fairly high maintenance cost. It becomes disabled by default and will be removed in a future version.
- JEP 372: Remove the Nashorn JavaScript Engine. Nashorn has been integrated into Java 8, deprecated in Java 11, and now removed. To execute JavaScript in the JVM you have to turn to GraalVM. Nashorn was no longer up to date with new versions of ECMAScript and its support was too expensive while a quality alternative exists with GraalVM.
Performance
Each release brings its share of performance improvements, both in peak performance and in start-up time.
And the release 15 have some important optimizations:
- G1: The default Garbage Collector has had several improvements in this release, the most interesting is the one described in the article by Stefan JohanssonImproving G1 out-of-the-box performance which allows a better calculation of the size of the heap regions, especially when the Xmx and the Xms are not the same.
- ZIP lookup: When starting a JVM, it will search (lookup) for entries (classes, resources) in JARs (which are ZIP), significant improvements have been made by a serie of patchs which leads to a gain not negligible for reading these entries. Details are on Claes Redestad’s blog Zip lookups – a word from the sponsor
- StringConcat: String concatenation is optimized from Java 9 via a StringConcatFactory. This one has been refactored to take less time to start as well as to optimize for the most classic cases of concatenation.
- AppCDS: Application Class Data Sharing is a feature that allows you to create an archive of class metadata to load when starting a JVM, this avoids searching on the disk, reading and parsing a class (small description of AppCDS here). With Java 15, the metadata of lambdas are added to the archive.