Java Release: The New Features in JDK 13

Are you curious about the latest from Java? Our Java expert will keep you up-to-date with this review of the new Java 13. Along with a breath of cool air, this fall has brought some fresh news to the software development world: Java 13 is here with new features!

Smaller But More Frequent Java Releases

In the IT community, Java is the most popular programming language for mobile, desktop and cloud applications. In the past, there was no well-defined schedule for Java releases: they could take from 2 up to 5 years. Then, starting with the release of Java 10, Oracle successfully switched to a six-month release cycle and feature improvements became fewer and more predictable for software engineers.  

This vastly improves the productivity of software developers at the time of a Java release so they can more readily utilize and go granular with the enhancements. Nowadays, Java releases present a small number of new features on a regular schedule: twice a year, in March and September. Java 13 was released per the schedule on September 17th. So, let’s look at the updates contained in JDK 13.

Java 13: What’s New?

Let’s start with the numbers. The Open JDK Community reports that 2,126 JIRA issues were fixed in JDK 13, 70% of these were settled by Oracle employees and 30% by individual contributors and large organizations such as Google, Red Hat, SAP, and more. 

All in all, the Java 13 release resulted in five improvements, including two preview features:

  • Garbage collection enhancement
  • Application class-data sharing
  • Legacy Socket API reimplementation
  • Switch expressions
  • Text blocks

Let’s now have a closer look at these updates in JDK 13, one by one, with code samples.

JEP 354: Returning Values From Switch Expressions

Switch expressions were introduced in Java 12. Break is used here to define return values:

boolean toBeOrNotToBe = switch (new Random().nextBoolean()) { case TRUE -> { System.out.println("To Be!"); break true; } case FALSE -> { System.out.println("Not to be"); break false; } }

Break true looks a little bit weird, though, even to developers who are very familiar with Java. That’s why it was decided to use the new keyword yield instead of break in Java 13. It is much clearer and can be used in other places to return values in future. Now, switch expressions look this way:

boolean toBeOrNotToBe = switch (new Random().nextBoolean()) { case TRUE -> { System.out.println("To Be!"); yield true; } case FALSE -> { System.out.println("Not to be"); yield false; }

This is a good example of how shorter release cycles have had a positive influence on the development of the Java programming language. After the 12th release of Java, a big part of the Java community agreed that the new usage of break isn’t a good idea. As a result, in the next JDK 13 release, it was changed to yield, which looks much more natural.

JEP 355: Text Blocks

Almost all Java engineers have seen SQL, XML or JSON inside the String variables, for example: 

String json = "" + "{\n" + "language: \"Java\",\n" + "version: \"13\",\n" + "description: \"is here\"\n" + "}\n";

Not exactly the most beautiful coding. But now, with Java 13, a JSON in String can be written like this:

String jsonBlock = """ { language: "Java", version: "13", description: "is here" } """;

Now that’s a bit of coding to be proud of! Text blocks is a new, straightforward preview feature that spans multiple lines.

The text block syntax involves:

  • Beginning your string with three double quotation marks “””, and a new line.
  • Ending the string with three double quotation marks “””.

The opening delimiter must be followed by a line terminator because text blocks cannot be used on a single line.

After compilation, text blocks become absolutely indistinguishable from strings created by literals. That’s why json.equals(jsonBlock) returns true.

To support Text blocks, three new methods were added:

  • formatted(): formats the string using the string itself as the format string. Basically it’s an equivalent to format(this, args).
  • stripIndent(): removes incidental spaces from the string. 
  • translateEscapes(): returns a string with escape sequences, (e.g. \r) translated into the appropriate Unicode value.

JEP 350: Dynamic CDS Archives

The application class-data sharing (AppCDS) feature was released in Java 10 and improved in Java versions 12 and 13. The goal of this feature is to reduce launching time by up to 50%. This is done by means of mapping classes that are used in application from JARs to special archives that AppCDS maps into the memory when JVM launches. Loading classes from the AppCDS archive is much faster than loading the same classes from JARs. 

To illustrate, with Java 10,we had to do the following steps:

  • create a list of classes to archive
  • create the archive
  • launch with the archive

With Java 13, we can make the archive by running the application with the new flag -XX:ArchiveClassesAtExit=<archive name>:

java -XX:ArchiveClassesAtExit=dyn-cds.jsa -jar target/java-x.jar

After that, we can run the application using the created archive:

java -XX:SharedArchiveFile=dyn-cds.jsa -jar target/java-x.jar

This method using the dynamic CDS archives seems less troublesome, doesn’t it? Try out this Java update right now in JDK 13 and see if you agree!

JEP 351: ZGC: Uncommit Unused Memory

Oracle’s Z Garbage Collector(ZGC) was introduced in Java 11 with the following goals:

  • Pause times to not exceed 10ms.
  • Pause times to not increase with the heap or live-set size.
  • Handle heaps ranging from a few hundred megabytes to multi terabytes in size.

In Java 13, it was improved to return unused memory to the operating system. This is done by providing a new flag -XX:ZUncommitDelay=<seconds>. After a specified time ZGC returns unused memory.

There is a new flag -XX:SoftMaxHeapSize that configures GC to try and limit the heap to the specified size. If it’s not possible, then GC will use the amount of memory specified in -Xmx.
Nowadays, applications work under high load, serving simultaneously millions of requests, and they require a good deal of memory to perform well. With ZGS supporting the release of unused memory, applications now consume much less memory throughout their effective lifetime.

JEP 353: Reimplement the Legacy Socket API

The implementation of java.net.Socket and java.net.ServerSocket is quite old and based on the legacy mix of the native and Java code. As a result, maintenance and extensibility have become quite difficult for developers. Moreover, this code conflicts with the new Loom’s approach where fibers (light-weight threads) should be used. In preparation for future changes, this API was reimplemented in JDK 13.

To Conclude

The Java 13 release doesn’t have a large number of new features — only five JDK Enhancement Proposals and 76 new core library elements. They provide improvements in present  performance, stability and security that aim to improve developer productivity and code clarity. JDK 13 also removed and deprecated a number of features, for example: Runtime Trace Methods, Pre-JDK 1.4 SocketImpl Implementations, the Internal com.sun.net.ssl Package, Old Features from javadoc Tool, and other options that will no longer be supported.

Now that the Java release cycles have become shorter, we are able to see and try out new features much more often. The Java development team also benefits because these changes lead to more consistent feedback from the IT community. This is especially true for the preview features that should be finalized (or eventually removed) in future Java updates or releases. We are already preparing for Java 14 and excited to learn what the next release has in store for us come March 2020 when, presumably, one of the updates will include finalized preview features from Java 13. 

Remaining the #1 choice by software developers around the world, the Java platform continues to evolve step-by-step through continued gradual enhancements and great teamwork. To enjoy the new Java 13 features with us, you may download the JDK 13 builds from jdk.java.net website