Every half a year, new Java is here!

Java 13 – a deep dive into the JDK’s new features

Falk Sippach
© Shutterstock / Surawit K. Sakul

Java expert Falk Sippach celebrates the release of Java 13 in this article talking about what’s new, why it matters and what it means for the future of the programming language.

You can tell this year sped by in a flash because Java’s version number has already increased by two! Meanwhile, we Java developers should have got used to the short release cycles. After all, we can now regularly try out new functions and are not killed every few years by a huge range of new features. In this article we take a look at Java 13, which is released today, September 17th, 2019.

Java 13 at a glance

The following Java Enhancement Proposals have made it into JDK 13:

  • JEP 350: Dynamic CDS Archives
  • JEP 351: ZGC: Uncommit Unused Memory
  • JEP 353: Reimplement the Legacy Socket API
  • JEP 354: Switch Expressions (Preview)
  • JEP 355: Text Blocks (Preview)

At first glance, it doesn’t look like much. In fact, due to the short time since the release of Java 12, we can’t really expect too many changes. Instead, the releases between the Long-Term Support (LTS) versions are mostly there to offer certain features as previews in order to get early feedback from the users. The functions are implemented in the JEPs and – as soon as they have reached a certain maturity – delivered with the next release of the defined half-yearly cycle.



This makes it impossible to predict exactly how many new functions relevant to the typical Java programmer will be included in the next release. The goal is to finalize the preview features by the next LTS version so that they are stable enough and will look good for the next three years. In September 2021, Java 17 will take over the legacy of Java 8 and 11.

Enhancements for Switch Expressions

If you look at the feature list above from a developer’s point of view, it’s the last two points that are mainly interesting. For example, the Switch Expressions introduced as a preview in Java 12 have been extended due to user feedback. The Switch Expression is an alternative to the cumbersome and error-prone Switch Statement. A detailed overview of its use can be found in various articles on Java 12.

The biggest change in Java 13 is the replacement of the keyword break in the switch expression by yield. The background is the better differentiation between switch statement (with possible break) and expressions (with yield). The yield statement exits the switch and returns the result of the current branch, similar to a return.

A code example follows in Listing 1. Above, we see a statement with break and fall through. In the direct comparison follows a switch expression with the new keyword yield and multiple labels. In contrast to the first variant, no variable is changed, but the result of the case branch is returned directly.

// Switch-Statement with break
private static String statementBreak(int switchArg){
  String str = "not set";
  switch (switchArg){
    case 1:
    case 2:
      str = "one or two";
    case 3:
      str = "three";
  return str;
// Switch-Expression with yield
private static String expressionBreakWithValue(int switchArg){
  return switch (switchArg){
    case 1, 2: yield "one or two";
    case 3: yield "three";
    default: yield "smaller than one or bigger than three";

The Arrow syntax introduced in Java 12 still works (Listing 2).

private static String expressionWithArrow(int i) {
  return switch (i) {
    case 1, 2 -> "one or two";
    case 3 -> "three";
    default -> "smaller than one or more than three";

Switch Expressions remain in preview for the time being, so there could be further adjustments in future Java versions. When compiling with JDK 13, the corresponding flags must therefore be specified:

javac --release 13 --enable-preview

The preview feature must also be activated at startup. Of course, build tools (Maven, etc.) also have configuration switches:

java --enable-preview Examples

Text Blocks instead of Raw String Literals

Text blocks are actually only a small part of the Raw String Literals (JEP 326) originally planned for Java 12. The first implementation of Raw String Literals was not yet thought through down to the last detail, users’ feedback raised many questions. The exact details can be found in the mailing list. Java 13 “only” has multi-line text blocks for now.

But that’s better than nothing. After all, many Java applications process code snippets from other languages such as HTML or SQL, which usually consist of several lines for the sake of clarity. Until now, such strings could only be defined in a very cumbersome way, which makes them difficult to read. For example, extra control commands (escaping with \n) must be used for line breaks. Other languages such as Groovy, Scala or Kotlin have long offered the possibility of defining multi-line texts.

The new text blocks use triple quotation marks as delimiters and can be used wherever normal strings are allowed. Listing 3 shows the differences between traditional and new syntax. The opening and closing triple quotes must be in a separate line. Nevertheless, the actual content starts with the second line. This increases the readability of the source code, as the indentation of the first line is displayed correctly in the source text.

// Without Text Blocks
String html = "<html>\n" +
          	"	<body>\n" +
         	 "      <p>Hello, Escapes</p>\n" +
          	"	</body>\n" +
// With Text Blocks
String html = """
              	<p>Hello, Text Blocks</p>

Further examples can be found in Tim Zöller’s article, which deals specifically with JEP 355. Text blocks are replaced by normal strings at compile time; in the byte code, you can no longer see how the string was originally defined.

Dynamic CDS Archives

Besides the new features that are obvious to developers, a lot has happened under the hood of the JVM and in the class library. Class Data Sharing (CDS) was introduced back in Java 5. The goal of CDS is to shorten the start times of Java applications by storing certain information about classes in Class Data Sharing archives. This data can then be loaded at runtime and used by several JVMs.

Until Java 10, however, the shared archives were only accessible for the Bootstrap Class Loader. Starting with Java 10, CDS was extended by Application Class Data Sharing (AppCDS). AppCDS enables the built-in system and platform class loader as well as user-defined class loaders to access the CDS archives. Class lists are required to create the CDS archives in order to identify the classes to be loaded.

SEE ALSO: Java 13 – why text blocks are worth the wait

Previously, these class lists had to be determined by trial runs of the application to determine which classes were actually loaded during execution. Since Java 12, default CDS archives are delivered with the JDK by default, which are based on the class list of the JDK.

Dynamic CDS Archives now build on this. The goal is to save the additional test runs of the application. After an application has been executed, only the newly loaded application and library classes that are not already contained in the Default/Base Layer CDS are archived. Dynamic archiving is activated with command line commands. In a future extension, the archiving of classes could then run completely automatically and transparently.

ZGC returns unused storage

Nowadays it is not uncommon that applications have to serve many thousands of users at the same time. These applications need a lot of memory, the management of memory is not trivial and affects the performance of the application. To meet these requirements, Oracle introduced the Z Garbage Collector (ZGC) in Java 11. It promises very short pauses when cleaning up heap memories with several terabytes.

Previously, however, it did not release the heap memory reserved for the application. As a result, applications usually consume far more memory than necessary over their lifetime. Applications that run in low-resource environments are particularly affected. Other garbage collectors such as the G1 and Shenandoah already support the release of unused memory.

Renewed Socket APIs

The and APIs and their underlying implementations are remnants from the JDK 1.0. Most of them consist of legacy Java and C code. This makes maintenance and extensibility much more difficult. The NioSocketImpl is supposed to replace the outdated PlainSocketImpl now. NioSocketImpl is based on the already existing New I/O implementation and uses its existing infrastructure in the JDK.

The previous implementation is also not compatible with other planned extensions of the language. For example, concurrency problems hinder the future use of the lightweight user threads (fiber, part of the Project Loom).


The changes described so far were defined in the JEPs (Java Enhancement Proposals). There are, however, further adaptations directly in the class library. These can be visualized using either the JDK API Diff Report Generator or the Java Almanac. A closer look reveals that the old Doclet API has been removed from com.sun.javadoc. Also, three new instance methods have been added to the String class as part of JEP 355 (Text Block): formatted, stripIndent and translateEscapes.

Since Java 10 we can look forward to new Java releases twice a year (March and September). Since of course not so much can happen in development in half a year, the respective feature lists are fortunately manageable. However, the short update cycles allow us to regularly try out the new features at short intervals. And the Java team at Oracle gets faster and more valuable feedback on the new features, some of which are in preview status for one or more releases. On the way to the next LTS version there will be user feedback and changes if necessary. For example, in the current LTS release Java 11 the work started in Java 9 and 10 was finalized.

For the productive use of its Java applications one can meanwhile choose between two variants. Either you stay with the current LTS release for three years or you update twice a year to the major version of the OpenJDK, which is updated by Oracle for half a year. The latter may be used freely, but must be updated to the next version after six months in order to continue to receive security updates and patches. With the LTS version, there are both paid offers (Oracle, Azul, …) and free installations such as AdoptOpenJDK, Amazon Corretto, RedHat, SAP and Alibaba Dragonwell. After the first surprise about Oracle’s new licensing policy, there are now a lot of alternatives to run Java in production.

In addition, Oracle’s idea seems to work with the semi-annual major releases and regular, albeit small, updates. So far the versions have been delivered on time as announced, so we can already look forward to the next changes. But first we have to install JDK 13 and try out the new features. Work on Java version 14 is already running in parallel. At the time this article was written, the JEP 352 (Non-Volatile Mapped Byte Buffers) was already planned. In addition, the previews of switch expressions and text blocks may be finalized. In addition, a new tool for packaging self-contained Java applications could appear within the framework of JEP 343. But as uncertain as these changes may seem at this point in time, the next release is already on its way. Because in March 2020, we’ll get to say, “every half year” again…


Falk Sippach

Falk Sippach has over fifteen years of experience in the Java and JavaScript world and works as a trainer, software developer and project manager at OIO Orientation in Objects GmbH. When he has time, he also writes blog entries and articles, and occasionally appears at conferences. In his adopted home Darmstadt he organizes the local Java User Group together with others.

1 Comment
Inline Feedbacks
View all comments
Kote Isaev
Kote Isaev
2 years ago

” NioSocketImpl is based on the already existing New I/O implementation and uses its existing infrastructure in the JDK.” – I thought Nio is for “non-blocking I/O, not “New I/O”….