JDK 14 was officially GA released on 17 March 2020.

These major releases are much more frequent in past years. However, I still find the release notes not an ideal source in providing a quick overview of what is new in the release. Hopefully this blog helps highlight what those exciting new features are.

358:  Helpful NullPointerExceptions

Finally, a helpful messages to pinpoint where null value actually is in the line. Make sure -XX:+ShowCodeDetailsInExceptionMessages flag is passed to java runtime.

class Address { String street; String zipCode; }
class Profile { String name; Address address; }

String zip = p.address.zipCode; 

Yield an exception that exactly describe what is being wrong.

java.lang.NullPointerException: 
Cannot read field "zipCode" because "p.address" is null

361: Switch Expressions (Standard)

Becomes a standard feature after preview in Java 12. Switch is now an expression which can return value using -> syntax.

var text = switch (number) {
    case  1 -> "one";
    case  2 -> "two";
    default -> "many";
};

Preview Features

To use these features,  The flag --enable-preview needed to be passed to javac during compile time.

368:  Text Blocks (Second Preview)

Supports Multiline text and intelligently trim the leading spaces.

The compiler will look at the minimum number of  spaces from all text lines. Then it take that value as the exact amount of  spaces to remove from every line. An obvious caveat is that there has to be a newline before and after """ (unlike in Python)

var text = """
           Multiline
           Text
           """;
           
// Automatically trim leading whitespace
assertEquals("Multiline\nText\n", text);

305:  Pattern Matching for instanceof (Preview)

No longer needed to cast an instance of object after it is checked.

Object obj = 1;
if (obj instanceof Integer i) {
    //Compiler recognize `i` as Integer. No need for casting
    var longVal = i.longValue();
    assertEquals(1L, longVal);
}

359:  Records (Preview)

This feature is very similar to Kotlin Data Classes and Scala Case Classes.

Now we can define a type that has a constructor, toString, hashCode and equals automatically generated. Each field also is effectively final.

record Person(String firstname, String lastname) {
    public String getName() {
        return firstname + " " + lastname;
    }
}

///////////////////

final var p = new Person("Hello", "World");

assertEquals(new Person("Hello", "World"), p, "Equality implemented");
assertEquals("Person[firstname=Hello, lastname=World]",
        p.toString(),
        "toString() implemented");

assertEquals("Hello", p.firstname, "Member");
assertEquals("Hello", p.firstname(), "Accessor");

// Won't compile - Cannot assign a value to final variable 'firstname'
// p.firstname = "New"; 

assertEquals("Hello World", p.getName(), "Custom method");

Other Features

These are some additional features that I personally find interesting.

  • JEP 343: Packaging Tool (Incubator) - Create a standalong java package to run from any platflom without requiring target platform to pre-install Java.
  • JEP 370: Foreign-Memory Access API (Incubator)

Gradle Project

All changes and flags are collected in this github repo.

varokas/java-versions
Contribute to varokas/java-versions development by creating an account on GitHub.

Tools Requirements

At the time of this post, many popular tools has JDK 14 support only in their Preview / Beta releases.

  • Java 14 SDK
  • Gradle 6.3 (currently in RC. Any version lower than 6.3 will not work because of Issue #10248 )
  • Intellij 2020.1 (currently in EAP)
  • Compile and run java with correct flags for preview features.

Using SDKMan helps installing Java/Gradle with ease.

$ sdk install java 14.0.0.hs-adpt
$ sdk install gradle 6.3-rc-4

After importing the project in IntelliJ, make sure JDK 14 is being used for both Project SDK and Gradle. Language level should be 14 (Preview) for all the preview features to be highlighted correctly.