What's new in Java 14

- Tom Trapp

And again, another half of a year is over and we're getting a new major JDK version, namely JDK 14! What's new, what got replaced, changed or removed? Let's find out together.

Pattern matching instanceof

The first new feature is the pattern matching for the instanceof functionality. Unlike what you may think of as in pattern matching used in regex expressions, pattern matching in Java 14 is a way to avoid redundant type casting on a single line expression. Before this feature, your code would look like this with redundant castings such as here:

boolean isObjectNullOrEmpty(Object obj) {
  return  obj == null ||
    obj instanceof Collection && ((Collection) obj).isEmpty() ||
    obj instanceof String && ((String) obj).isBlank();
}

That is just a simple method isObjectNullOrEmpty() which check if an object, which could be String or Collection, is null or empty. How cool would it be to assign the instanceof check object to an inline variable? Well, take a look at this here:

boolean isNullOrEmpty(Object obj) {
  return o == null ||
    obj instanceof Collection c && c.isEmpty() ||
    obj instanceof String s && s.isBlank();
}

We are assigning the object if it is a Collection to the variable c and running method usages directly on the very same variable. Of course, this is null-safe, since we are using the 'logical and' operator where the right side is only executed if the left statement returns true.

Helpful NullPointerExceptions

The next new feature, which is currently only available in preview mode, is a more helpful NullPointerException. As a Java developer, it is quite important to check for null references in your code if that ever happens. Of course, you also know that important null checks might be missed out more often than not. Prior JDK 14 it was often quite challenging to find out which variable ended up being responsible for the null pointer.

JDK 14 adds a new java option which displays a more accurate output whenever NPEs occur which makes it easier to pinpoint down where the NPE actually happened. You can enable this optional feature by adding the following java flag:

XX:+ShowCodeDetailsInExceptionMessages

For example, the following code would produce the following longer and more telling log error if any NPE would occur on that line:

women.partner().firstName()

java.lang.NullPointerException: Cannot invoke "Human.firstName()" because the return value of "Human.partner()" is null

New type - Records

Java 14 introduces a new type, namely the Record. A Record is quite similar to a Kotlin data class. In the past, there were tons of various data classes using generic getter and setter methods or even lombok annotations. The Record type adds an compact syntax of defining such data classes, for example your Human class from the previous topic would look as short as this:

public record Human( String firstName, String lastName, Person partner ) {}

And that's all you need! The compiler does generate an immutable (!) class including constructor, all the final instance variables with accessor methods (not getters however), hashcode, equals and toString() methods for you.

public final class Human extends Record {
  private final String firstName;
  private final String lastName;
  private final Person partner;
   
  public Person(String firstName, String lastName, Person partner) { this.fristName = fristName; this.lastName = lastName; this.partner = partner; }
 
  public String toString() { /* ... */ }
  public final int hashCode() { /* ... */ }
  public final boolean equals(Object o) { /* ... */ }
  public String firstName() { return this.firstName; }
  public String lastName() { return this.lastName; }
  public Person partner() { return partner; }
}

Of course, you can specify other static fields or methods by using annotations or by declaring another constructor or another instance method. This is not a typical Java Bean since the class is immutable and doesn't have any getters. As such, the values stored in an object are final and cannot be changed after having been generated.

Text Blocks

If you have been following major Java announcements in the past, you may be wondering what to do with the addition of Text Blocks features. Yes, this is the second preview version of this feature: it allows you to do pretty much the same thing, namely to structure multiline Strings properly.

// Without Text Blocks
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, old way</p>\n" +
              "    </body>\n" +
              "</html>\n";
 
// With Text Blocks
String html = """
              <html>
                 <body>
                    <p>Hello, new way with Text Blocks</p>
                 </body>
              </html>""";

Furthermore, with Java 14 two new escape sequences were introduced: The first one is the famous backslash where you can split your String declaration onto several lines without generating any annoying linebreaks in the output:

// Without Text Blocks
String literal = "Lorem ipsum dolor sit amet, consectetur adipiscing " +
                 "elit, sed do eiusmod tempor incididunt ut labore " +
                 "et dolore magna aliqua.";

//With Text Blocks
String text = """
                Lorem ipsum dolor sit amet, consectetur adipiscing \
                elit, sed do eiusmod tempor incididunt ut labore \
                et dolore magna aliqua.\
                """;

What else?

Regarding major syntax changes, this is more or less everything.

For the rest, let's keep it short: The FileChannel API was extended to be able to work with MappedByteBuffer only on GNU/Linux for now. Some things regarding garbage collectors have been changed, also the Concurrent Mark Sweep (CMS) Garbage Collector got removed, finally the ZGC is now available for Windows and macOS.

With the new biannual release cycle of Java, the features are growing within the major releases from preview to standard to be production ready for the next iteration of the next version, which is going to be in fall 2021 with version Java 17.

Make sure to check out our website and blog in order to stay up to date. The next JDK version is already coming in September!