Skip to content

Java 13 – New features and enhancements

Oracle are now releasing a new version of Java in March and September of every year. Java 13 was released on September 17th, 2019. It reached General Availability on 17 September 2019. Production-ready binaries under the GPL are available from Oracle; binaries from other vendors will follow shortly, as announced on OpenJDK official site.

JDK 13 will receive a minimum of two updates, per the Oracle CPU schedule, before being followed by Oracle JDK 14, which is due out in March 2020, with early access builds already available.

Five new features are introduced in Java 13.

Features

Dynamic CDS Archives
ZGC: Uncommit Unused Memory
Reimplement the Legacy Socket API
Switch Expressions
Text Blocks

Dynamic CDS Archives

CDS which stands for  application class-data sharing allows dynamic archiving of classes at the end of Java application execution. The archived classes will include all loaded application classes and library classes that are not present in the default, base-layer CDS archive.

Class Data Sharing (CDS) improves startup performance by creating class-data archive once and then reuse it, so that the JVM need not recreate it again.

ZGC: Uncommit Unused Memory

This feature helps returning unused heap memory to the operating system.

ZGC does not currently uncommit and return memory to the operating system, even when that memory has been unused for a long time. This behavior is not optimal for all types of applications and environments, especially those where memory footprint is a concern. For example:

  • Container environments where resources are paid by use.
  • Environments where an application might be idle for long periods of time and is sharing or competing for resources with many other applications.
  • An application might have very different heap space requirements during its execution. For example, the heap needed during start up might be greater than what is needed later during steady state execution.

Other garbage collectors in HotSpot, such as G1 and Shenandoah, provide this capability today, which some categories of users have found very useful. Adding

Reimplement the Legacy Socket API

This feature aims to replace the underlying implementation used by the java.net.Socket and java.net.ServerSocket APIs with a simpler and more modern implementation that is easy to maintain and debug. The new implementation will be easy to adapt to work with user-mode threads, a.k.a. fibers

In Java 13, a new NioSocketImpl class is introduced as a drop-in replacement for PlainSocketImpl. However, if something goes wrong, we can still switch back to the old implementation PlainSocketImpl by setting jdk.net.usePlainSocketImpl system property

ServerSocket is modified to use NioSocketImpl (or PlainSocketImpl) by default. It no longer uses the SOCKS implementation.

The SocketImpl implementations to support SOCKS and HTTP proxy servers are modified to delegate so they can work with the old and new implementations.

The instrumentation support for socket I/O in Java Flight Recorder is modified to be independent of the SocketImpl so that socket I/O events can be recorded when running with either the new, old, or custom implementations.

To reduce the risk of switching the implementation after more than twenty years, the old implementation will not be removed. The old implementation will remain in the JDK and a system property will be introduced to configure the JDK to use the old implementation. The JDK-specific system property to switch to the old implementation is jdk.net.usePlainSocketImpl. If set, or set to the value true, at startup, then the old implementation will be used. Some future release will remove PlainSocketImpl and the system property.

Switch Expressions

The current switch statement can be used as an expression.

static void howMany(int k) {
    System.out.println(
        switch (k) {
            case  1 -> "one"
            case  2 -> "two"
            default -> "many"
        }
    );
}

The common form of switch expression will be like the following.

T result = switch (arg) {
    case L1 -> e1;
    case L2 -> e2;
    default -> e3;
};

A new yield statement is introduced to yield a value, which becomes the value of the enclosing switch expression.

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        yield result;
    }
};

yield statement can also be used with the traditional switch statement.

int result = switch (s) {
    case "One": 
        yield 1;
    case "Two":
        yield 2;
    default:
        System.out.println("Neither One nor TWo");
        yield 0;
};

Text Blocks

Assigning a long string value to an Object has been a headache in Java. Thanks to text blocks, that’s not the case anymore.

String html = """
              <html>
                  <body>
                      <p>YAY TEXT BLOCKS</p>
                  </body>
              </html>
              """;

A text block consists of zero or more content characters, enclosed by opening and closing delimiters.

The opening delimiter is a sequence of three double quote characters (""") followed by zero or more white spaces followed by a line terminator. The content begins at the first character after the line terminator of the opening delimiter.

The closing delimiter is a sequence of three double quote characters. The content ends at the last character before the first double quote of the closing delimiter.

The content may include double quote characters directly, unlike the characters in a string literal. The use of \" in a text block is permitted, but not necessary or recommended. Fat delimiters (""") were chosen so that " characters could appear unescaped, and also to visually distinguish a text block from a string literal.

1 Comment »

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.