Liberica JDK 14 is generally available

March 18, 2020

By changing the cadence of OpenJDK releases two years ago, Oracle accelerated the evolution of Java, which was categorically a positive move for the platform and the ecosystem. Before the change, developers were waiting for the new version with stable features at least for three years. Today, we can admit that the Java run-time development process is iterative. Initially, new capabilities are injected into OpenJDK as previews features; the developer community is testing and giving its feedback to JEP leaders, and after a number of releases, the feature becomes standard. JDK 14 has sixteen new features in six areas: API, Runtime & Performance, Serviceability, Tools, Improved platforms support, and Deprecation.

API enhancements

JEP-361: Switch Expressions (Standard)

JEP-305: Pattern Matching for instanceof (Preview)

JEP-359: Records (Preview)

JEP-368: Text Blocks (Second Preview)

JEP-370: Foreign-Memory Access API (Incubator)

Run-time and Performance

JEP-358: Helpful NullPointerExceptions

JEP-352: Non-Volatile Mapped Byte Buffers

JEP-345: NUMA-Aware Memory Allocation for G1

Serviceability

JEP-349: JFR Event Streaming

JEP-343: Packaging Tool (Incubator)

Improved platforms support

JEP-364: ZGC on macOS

JEP-365: ZGC on Windows

Deprecation

JEP-362: Deprecate the Solaris and SPARC Ports

JEP-366: Deprecate the ParallelScavenge + SerialOld GC Combination

JEP-363: Remove the Concurrent Mark Sweep (CMS) Garbage Collector

JEP-367: Remove the Pack200 Tools and API

Let’s look at some new features in details.

API enhancements

Switch Expressions (Standard) JEP-361

This feature extended switch statement, which can be used as an expression with the help of arrow (->), and now can yield/return the value.

Before JDK14

switch ( day ) { case MONDAY , FRIDAY , SUNDAY -> System . out . println ( 6 ); case TUESDAY -> System . out . println ( 7 ); case THURSDAY , SATURDAY -> System . out . println ( 8 ); case WEDNESDAY -> System . out . println ( 9 ); } switch ( day ) { case MONDAY: case FRIDAY: case SUNDAY: System . out . println ( 6 ); break ; case TUESDAY: System . out . println ( 7 ); break ; case THURSDAY: case SATURDAY: System . out . println ( 8 ); break ; case WEDNESDAY: System . out . println ( 9 ); break ; }

JDK 14

JDK14 makes the syntax more precise and removes boilerplate.

switch ( day ) { case MONDAY , FRIDAY , SUNDAY -> System . out . println ( 6 ); case TUESDAY -> System . out . println ( 7 ); case THURSDAY , SATURDAY -> System . out . println ( 8 ); case WEDNESDAY -> System . out . println ( 9 ); }

Pattern Matching for instanceof (Preview) JEP-305

Before JDK14

if ( o instanceof Foo ) { Foo f = () o ; System . out . println ( f . getName ()); }

JDK 14

if ( o instanceof Foo f ) { System . out . println ( f . getName ()); }

This is the first step to other changes. But it’s already possible to combine Switch expressions with instanceof pattern matching and create much cleaner code.

Before JDK14

@Override public void onReceive ( Object msg ) { if ( msg instanceof ClusterMessage ) { onMsg (( ClusterMessage ) msg ); } else if ( msg instanceof RpcBroadcastMsg ) { onMsg (( RpcBroadcastMsg ) msg ); } ....... }

JDK14

@Override public void onReceive ( Object msg ) { switch ( msg ) { case ClusterMessage cm -> onMsg ( cm ); case RpcBroadcastMsg rbm -> onMsg ( rbm ); ... } }

Records (Preview) JEP-359

Before JDK14, a data class would look like below with getters, setters, equals, hashcode, toString, and so on. To somehow get rid of all that mess, a widely adopted Lombok library was created. Also, you could rely on your IDE.

public class Station { private String name ; private Coordinates coordinates ; public String getName () { return name ; } public void setName ( String name ) { this . name = name ; } public Coordinates getCoordinates () { return coordinates ; } public void setCoordinates ( Coordinates coordinates ) { this . coordinates = coordinates ; } @Override public boolean equals ( Object o ) { if ( this == o ) return true ; if ( o == null || getClass () != o . getClass ()) return false ; PlainStation that = ( PlainStation ) o ; return Objects . equals ( name , that . name ) && Objects . equals ( coordinates , that . coordinates ); } @Override public int hashCode () { return Objects . hash ( name , coordinates ); } @Override public String toString () { return "PlainStation{" + "name='" + name + '\'' + ", coordinates=" + coordinates + s '}' ; } }

With JDK14 the same data-class can be declared as Record with only one line of code. The class will already have all getters, setters etc.

public record RecordStation ( String name , List < Coordinates > coordinates ) {}

Text Blocks (Second Preview) JEP-368

In JDK13 Text Blocks was introduced with JEP-355. JDK14 evolves (or, better say, reconsiders) this feature, which is useful for some DSLs. For example, we used it for JOCL (Java binding for OpenCL)

private static String vertexShaderSource = """ #version 150 core in vec4 inVertex; in vec3 inColor; uniform mat4 modelviewMatrix; uniform mat4 projectionMatrix; void main(void) { gl_Position = projectionMatrix * modelviewMatrix * inVertex; } """ ;

New Java language features have well-known analogs in Kotlin.

These features are already supported since IntelliJ IDEA 2020.1, while JetBrains engineers, together with Oracle and other OpenJDK contributors, worked on feature design and implementation.

Foreign-Memory Access API (Incubator) JEP-370

There are some third-party tools like Ignite, mapDB, memcached, to work with off-heap memory. Now Java will have its native API to do the same with new abstractions MemorySegment, MemoryAddress, and MemoryLayout.

Deprecation

Evolution is not just about adding new capabilities. Evolution is also a removal of rudiments. A new cadence allows quick disposal of outdated features. In JDK14, Solaris port will be decommissioned. Solaris 11 will be the end of support in 2035. Users who need to have Java for Solaris should stay on LTS versions: JDK8 or JDK11.

To download Java SE verified binaries of Liberica JDK 14 go here