Stay up to date with JDK 14 news

Java 14: All the new features of JDK 14 as it hits GA

Chris Stewart
Java 14
© Software & Support Media GmbH / Bianca Röder

Java 14 is finally here. Java 12 and Java 13 each came with a manageable number of new features, and thanks to the new release cadence that hasn’t changed for Java 14. We’ve kept track of JDK 14 from the very start, so we’re very excited that the big day is finally here!

Yes, six months have gone by so quickly and now here we are, the release of Java 14 is upon us. We’ve kept track of the new JDK’s progress over the last half a year and you can find all the features summarized here for you.

However, if you want to jump right in, you can find the JDK 14 binaries here.

Java 14 – The facts

The first step on the road to the next Java release was taken in June when the Expert Group was formed. The group includes members such as Simon Ritter (Azul Systems), Manoj Palat (Eclipse Foundation), Tim Ellison (IBM), Andrew Haley (Red Hat), Volker Simonis (SAP SE), Iris Clark (Oracle) and of course Brian Goetz (also Oracle).

JDK 14 brings 16 new features to the Java programming language. Some of them more interesting than others, and some of them more like housekeeping. Here’s a summary of the new features:

  • Pattern Matching for instanceof (Preview)
  • Packaging Tool (Incubator)
  • NUMA-Aware Memory Allocation for G1
  • JFR Event Streaming
  • Non-Volatile Mapped Byte Buffers
  • Helpful NullPointerExceptions
  • Records (Preview)
  • Switch Expressions (Standard)
  • Deprecate the Solaris and SPARC Ports
  • Remove the Concurrent Mark Sweep (CMS) Garbage Collector
  • ZGC on macOS
  • ZGC on Windows
  • Deprecate the ParallelScavenge + SerialOld GC Combination
  • Remove the Pack200 Tools and API
  • Text Blocks (Second Preview)
  • Foreign-Memory Access API (Incubator)

Let’s take a closer look at each of these in more detail.

Java 14’s features

The following JEPs are confirmed to target Java 14:

JEP 305: Pattern Matching for instanceof (Preview)

Over the course of Project Amber, pattern matching for Java is being worked on. For the instanceof operator, pattern matching in Java 14 has become a (preview) reality, making the Java programming language more concise and secure. With pattern matching, the “form” of objects can be precisely defined, after which they are tested against their own input by statements and expressions.

The use of pattern matching in instanceof could lead to a strong decrease of necessary type conversions in Java applications. In future Java versions, pattern matching could be used for further language constructs such as switch expressions.

JEP 343: Packaging Tool (Incubator)

Who would’ve thought we’d start to miss JavaFX again? With JDK 8, a tool called javapackager was released as part of the JavaFX kit. However, after JavaFX split from Java with the release of JDK 11, the popular javapackager was no longer available.

The packaging tool ensured that Java applications could be packaged in such a way that they could be installed like all other programs. For Windows users, for example, *.exe files could be created and their Java application installed by double-clicking. Since the tool is sorely missed, a new tool called jpackage is to pick up the mantle. Users can finally create their own Java installation files again, based on the Java application and a runtime image. The tool takes this input and creates an image of a Java application that contains all dependencies (formats: msi, exe, pkg in a dmg, app in a dmg, deb and rpm).

JEP 345: NUMA-Aware Memory Allocation for G1

Multi-core processors are now the general standard. In a NUMA memory architecture, each processor core receives a small amount of local memory, but the other cores are granted access to it. JEP 345 plans to equip the G1 Garbage Collector with the possibility to use such architectures advantageously. Among other things, this is intended to increase performance on very powerful machines.

JEP 345 serves exclusively for the implementation of NUMA support for the G1 garbage collector, only for memory management (memory allocation) and also only under Linux. Whether this support of NUMA architectures also comes for other garbage collectors or for other parts such as task queue stealing is not known.

JEP 349: JFR Event Streaming

The Java Flight Recorder (JFR) is now part of the OpenJDK and therefore freely available. JEP 349 creates an API, via which the data collected by the Java Flight Recorder can be used for the continuous monitoring of active and inactive applications. The same events are recorded as for the non-streaming variant, with an overhead of less than 1 percent. Event streaming would thus be carried out simultaneously with the non-streaming variant.

However, JEP 349 should not allow synchronous callbacks for the respective consumer, even data from recordings stored in the intermediate memory should not be made available. Technically, the package jdk.jfr.consumer in the jdk.jfr module would be extended by the functionality to access events asynchronously.

JEP 352: Non-Volatile Mapped Byte Buffers

JEP 352 extends MappedByteBuffer with the ability to extend access to non-volatile memory (NVM). This memory (also known as persistent memory) is used to store data permanently. This Java Enhancement Proposal brings a new module and class to the JDK API: The jdk.nio.mapmode module can be used to create the MappedByteBuffer (read-write or read-only), which is mapped via a file on an NVC.

The ManagementFactory class makes it possible to get a list of BufferPoolMXBean instances using the List getPlatformMXBeans(Class) method. This is modified so that it captures certain statistics for all MappedByteBuffer instances mapped by the above module.

JEP 358: Helpful NullPointerExceptions

Programs, and Java applications are no exception, usually consist of a multitude of methods, objects, functions, annotations and so on. And in this large collection of small parts a so-called NullPointerException (NPE) can occur practically everywhere. This problem is solved by JEP 358. By an analysis of the bytecode instructions of a program, in the future the JVM should be able to show precisely which variable results in a zero value. Then the JVM will output a null-detail message in the NullPointerException, which appears next to the usual message. The above example would look like this:

Exception in thread "main" java.lang.NullPointerException: 
        Cannot assign field 'i' because 'a' is null.
    at Prog.main(

Accordingly the message for a more complex example (a.b.c.i = 99;) would appear like this:

Exception in thread "main" java.lang.NullPointerException: 
        Cannot read field 'c' because 'a.b' is null.
    at Prog.main(

The aim of the JEP 358 is to provide authors and developers with important and helpful information for troubleshooting. New developers would be less confused and concerned about NPEs and the general understanding of a program could be improved.

JEP 359: Records

JEP 359 brings records as preview feature for Java. Records is a new type that was developed in the course of the Valhalla project. These – like enums – represent a restricted form of the declaration class. Records differ from classical classes in that they cannot decouple their API from its representation. But the freedom that is lost is compensated by the increased precision.

In the proposal for records it was said that a record is “the state, the whole state and nothing but the state”. It consists of a name, the status description and the body:

record Point(int x, int y) { }

Records remain classes, even if they are restricted. For example, they can contain annotations or Javadocs, and declare their bodies as static fields, methods, constructors, or instance methods. What they cannot do, however, is extend other classes or declare instance fields (with the exception of status components declared in the header of the record).

JEP 361: Switch Expressions (Standard)

With JEP 325 (Switch Expressions), it was proposed to extend the switch statement so that it can be used either as a statement or as an expression. Both forms should be able to use either “traditional” or “simplified” variables and control structures. The aim of this JEP was to simplify daily programming and pave the way for Pattern Matching (JEP 305) in conjunction with the switch statement.

This proposal initially changes the case notation. In addition to the obvious arrow instead of the colon, several values can also be listed for testing purposes since Java 12. It is especially remarkable that no break is needed anymore.

With JEP 354 Gavin Bierman suggested to adapt the functionality a little bit. To output a value from a switch expression, the value statement is to be replaced by a yield statement. Otherwise the Switch Expressions remained unchanged and should now be part of one of the next Java versions – maybe even part of Java 14.

JEP 362: Deprecate the Solaris and SPARC Ports

The Solaris operating system is still a part of the Sun Microsystems inventory and is no longer really up to date. Accordingly, Oracle’s wish to mark the ports for Solaris/SPARC, Solaris/x64 and Linux/SPARC as deprecated is not surprising. The next step, according to JEP 362, is to get rid of them in a future update. However, it should be noted that old Java versions (up to JDK 14) should run unchanged on old systems, including the corresponding ports.

The goal of the whole thing is to be able to take care of other features. However, if there is a group of dedicated and interested developers who want to maintain and administer the ports, the removal from the JDK could be overturned at a later date.

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

In Java 14, JEP 363, proposed by Thomas Schatzl, aims to remove the Concurrent Mark Sweep (CMS) garbage collector after it was marked as deprecated in Java 9 (JEP 291). According to Schatzl, interested users had two years to take care of the project. As this has not been the case so far, the last rites are now being prepared for Mark Sweep.

But users of older Java versions who rely on the CMS GC can breathe a sigh of relief – the goal is not to remove the garbage collector from earlier releases of the JDK. The same is true for other garbage collectors like Shenendoah or ZGC, even though this should go without saying; these remain in the JDK and have nothing to do with the new JEP.

JEP 364: ZGC on macOS

JEP 364, created by Erik Österlund, also deals with garbage collection. The goal of the proposal is to provide the Z Garbage Collector as an option for macOS users. Part of the JEP is also the functionality of the collector to free unused memory for the system, as suggested in JEP 351. This functionality has been included in the JDK since Java 13.

JEP 365: ZGC on Windows

JEP 365 is practically the same proposal as JEP 364, the only difference being that JEP 365 is about providing the Z Garbage Collector (ZGC) for Windows. The majority of the ZGC’s code base is platform-independent, so it should only be a small development effort to make it fit for Windows. There are limitations to its compatibility with older Windows versions – Windows 10 and Windows Server should not be older than version 1803, since older versions do not contain the API required for memory reservations.

JEP 366: Deprecate the ParallelScavenge + SerialOld GC Combination

JEP 366 is also about garbage collectors, or in this case a combination of two “garbage collectors”: ParallelScavenge and SerialOld. The suggestion is to mark the combination of the two algorithms as deprecated, since probably only very few developers use them in this constellation. In the end this is about the cost-benefit-factor, because to keep this combination up to date requires a considerable effort, relative to its actual use. However, the combination called via -XX:UseParallelGC and -XX:-UseParallelOldGC should not be completely removed. However, the Garbage Collector Parallel is a good alternative in the eyes of Thomas Schatzl, who suggested this JEP.

JEP 367: Remove the Pack200 Tools and API

The Pack200 compression theme, which is used to compress JAR files, has been marked obsolete since Java 11. JEP 367 is now the official proposal to remove the tools pack200 and unpack200 as well as the Pack200 API from the java.util.jar package. The technique was introduced in Java 5 at the time and served as a reaction to the then still very limited bandwidth (56k modems) and the low storage space on hard disks. Some time ago with Java 9, new compression schemes were introduced; developers are recommended to use jlink.

JEP 368: Text Blocks (Second Preview)

JEP 326 planned to add so-called Raw String Literals to the programming language already in version 12. Such a raw string literal can extend over several lines of code and does not interpret escape sequences such as \n or Unicode escape sequences such as \uXXXX. Unlike traditional string literals, the new, complementary raw literals should not be interpreted, but as they are generated as strings. So to speak “raw and untreated” they should make it easier for developers to express character sequences in a readable form and free of Java indicators. This JEP was much discussed and eventually put on the back burner as urgent revisions were needed, as Brian Goetz put it up for debate on the Amber Spec Experts mailing list. Dedicated Java developers were invited to provide input and participate in the process.

In Java 13, JEP 355 was included as a preview feature to introduce the new Text Block type. The JEP’s efforts were based on the foundations already laid for JEP 326 and the raw string literals. The text blocks described in the proposal are supposed to represent multi-line string literals according to the corresponding JEP draft. Their formatting should be subject to uniform rules and be based on the representation of the text in the source code, so that developers do not necessarily have to resort to commands to influence the layout of the text. One of the goals associated with the introduction of Text Block is to make it easier for programmers to create multi-line strings. The automatic formatting rules would not require \n style escape sequences when introducing the type. In particular, Java programs that contain code from other programming languages within strings should become more readable with the new format.

JEP 368 is now the second preview. Based on the feedback, two new escape sequences have been added to the feature that allow fine-grained control over the processing of newlines and whitespaces: \<line-terminator> and \s. The first escape sequence can be used to force a break for very long string literals without splitting them into smaller “substrings”.

An escape sequence without \<line-terminator>:

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

An escape sequence with \<line-terminator>:

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

The escape sequence \s can easily be described as a single space (\u0020). This ensures in the example below that the lines have exactly 6 digits and are no longer:

String colors = """
    red  \s
    blue \s

This escape sequence can be used in the new text blocks, but also in classic string literals.

JEP 370: Foreign-Memory Access API (Incubator)

There are tons of Java libraries and applications that access foreign memory. Prominent examples are Ignite, mapDB, memchaced or Nettys ByteBuf API. However, the Java API itself does not provide a good way to do this, although it can save costs on garbage collection (especially when managing large caches) and share memory across multiple processes. Serializing and deserializing memory contents via mappings of files in the memories is also possible by accessing foreign memory (e.g. via mmap).

With JEP 370, a suitable Java API is to be implemented in the JDK in Java 14, with which Java applications can securely and efficiently access foreign memory that is located outside the Java heap. The three premises are important: general validity, security and determinism.

The former means that a single API should work in conjunction with different foreign memories (native memory, persistent memory, etc.). The security of the JVM is the highest good, so the API should not be able to infiltrate it – no matter which memory is used. In addition (determinism), the release of memory should be explicit in the source code.

This JEP was developed in the course of the Project Panama and is a clear alternative to using existing APIs like ByteBuffer, Unsafe or JNI. Of course, the implementation helps to achieve the general maxim of the project: the support of native interoperability of Java.

Java 14 Release schedule

As always, Mark Reinhold shared the planned release schedule on the jdk-dev mailing list. This is how it unfolded:

Date Event
December 12, 2019 Start Rampdown Phase One
January 16, 2020 Start Rampdown Phase Two
February 6, 2020 First release candidate
February 20, 2020 Final release candidate
March 17, 2020 Release of Java 14

Preview of JDK 15’s features

We can also start to draw some conclusions about likely features for JDK 15 at this point; with two preview features and one incubator in JDK 14, it’s not unreasonable to think we might see pattern matching for instanceof or text blocks become fully grown, or that the packaging tool might graduate from its incubation status.

If you love Java, why not take a look at our Java 15 news?

Chris Stewart
Chris Stewart is an Online Editor for He studied French at Somerville College, Oxford before moving to Germany in 2011. He speaks too many languages, writes a blog, and dabbles in card tricks.

Inline Feedbacks
View all comments
Lorant Miglecz
Lorant Miglecz
2 years ago

Is it possible for anyone to be able to develop their own GC in java by implementing an API or something and use that instead of the built-in ones?