Reduce your TCO of building and using Spring Native applications with just 3 steps. Switch to the best Unified Java Runtime. Learn More.

JDK 14 - Moving faster on a new cadence

Liberica JDK 14 is generally available


Published 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 for at least three years. Today, we can admit that the Java run-time development process is iterative. Initially, new capabilities are injected into OpenJDK as preview 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

Tools

  • JEP-343: Packaging Tool (Incubator)

Improved platforms support

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 JDK 14

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

JDK 14 makes the syntax more precise and removes the 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 JDK 14

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 JDK 14

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

JDK 14

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

Records (Preview) JEP-359

Before JDK 14, 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 JDK 14, 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 JDK 13, Text Blocks was introduced with JEP-355. JDK 14 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;
        }
    """;

The 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, and 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 JDK 14, the 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: JDK 8 or JDK 11.

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

Author image

Alexander Belokrylov

BellSoft CEO

 LinkedIn