Java 15

Welcome to another release review. As one of my colleague pointed out, keeping up with releases takes time that we don’t have (since we are still on 11) but nevertheless we need to invest the time to make the transition easier to the next LTS which is gonna be Java 17. As you already noticed this is not a LTS release, which will stop many teams in the migration towards it. Without further ado let’s jump in it.

First we need to install it. On osx the steps are:

 brew update
 brew tap adoptopenjdk/openjdk
 brew search jdk 
 brew install --cask adoptopenjdk15

Also what I like to do is to be able to switch easily jdks. For that I have this script

jdk() {
        export JAVA_HOME=$(/usr/libexec/java_home -v"$version");
        java -version

in my .bash_profile file. I can simply run

jdk 15

to switch to java 15.

Sealed Classes

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

By writing this we specify which are the allowed sub-types. This is used in the context of inheritance. The intent is to provide more fine grain control over what can we expose. The subtypes or permitted types can be sealed, non-sealed or final. Final we already know we don’t allow inheritance, sealed we know from above and non-sealed means the free for all to inherit. We use the latter most of our time(unfortunately).

public final class Circle extends Shape {}
public non-sealed class Square extends Shape {}

public sealed class Rectangle extends Shape 
    permits RedRectangle, BlackRectangle {}
public final class RedRectangle extends Rectangle {}
public final class BlackRectangle extends Rectangle {}

This switch is somewhat built on top of the pattern matching for instanceof. We are allowed to write this because we know the types of shapes are finite.

float color = switch (shape) {
    case Circle c -> colorRed(c);
    case Rectangle r -> colorGreen(r);
    case Square s -> colorBlue(s);
    // no default needed!

This can be useful in the process of defining frameworks or libraries. Where the scope is narrowed and less flexibility is required. Now for most of us who are not developing frameworks or libraries you might wonder why we need it. And to be honest I don’t know. If we think of OOP and best practices we notice that this breaks the Open Close principle and we put a limit on polymorphism. Also inheritance should be used by taking into consideration the Liskov principle. Not to mention we must favour composition over inheritance. My feeling is that these releases are not necessarily for a wider audience, but a step in enhancing the language itself.

Hidden Classes

Again something that has little use for the vast majority of the java devs. It’s intended for low level devs(jvm and instrumentation). The idea is the now it’s possible to create classes that are visible in certain conditions(eg inside a framework only) and accessible via reflection. But outside the boundaries of the framework, reflection cannot see the hidden classes.

Shenandoah: A Low-Pause-Time Garbage Collector 

This is not an experimental feature anymore as it’s a production ready GC. Like the name said it’s a low pause GC, it runs concurrently with the program and it does not care about the amount of memory it collects, so the pauses should be similar.

The heap is structured in regions and a cycle has the following steps:

  • Init mark(Pause) – it scans the root set( local variables, references embedded in generated code, interned Strings, references from classloaders). The duration of the pause it’s proportional with the size of the set.
  • Concurrent mark – it walks the reachable objects. The active application may allocate new memory since it runs independently of the GC.
  • Final mark(Pause) – consumes all the marking queue and triggers rescan of the root set. Figures out which regions should be evacuated
  • Concurrent cleanup – reclaims the regions where no live objects are present
  • Concurrent evacuation – copies the live objects to other regions
  • Init Update Refs(Pause) – make sure all application threads have finished evacuation.
  • Concurrent Update References – updates the references to objects that were moved during concurrent evacuation
  • Final Update Refs(Pause) – re-updates the existing root set and clean up the garbage regions
  • Concurrent Cleanup – reclaims the regions with no references

For detailed information go to their wiki.

ZGC: A Scalable Low-Latency Garbage Collector

In Java 15, ZGC is production ready. Like Shenandoah, it will do the garbage collection while the application runs. It’s future goals are:

  • few milliseconds pauses
  • pause time independent of the heap(will not increase with the number of live objects)

Other features

I will mention here 2nd previews of pattern matching and record, and now the text blocks are now a standard feature. For more information on this go here.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.