What is new in Java 12 ?
Nov 15, 2018
5 minute read


This is an alive post of what will become Java 12, and, as expected, this post will expand and change over time, until the development of Java 12 is freezed probably at the end of 2018. I am planning to update this post when a new feature (JEP) is targeted for JDK 12, or when there is an important update on an already targeted JEP.

Last Update: 2018/11/28

This post uses JDK 12 Early-Access Builds. You may need to provide --enable-preview and -source 12 flags to javac and --enable-preview flag to java.

The Rampdown Phase One (RDP 1) of JDK 12 is due 2018/12/13. At RDP 1, the overall feature set is frozen.

If something is a preview feature, it is fully specified and implemented, but provided in a release to gather feedback, thus it is not permanent change yet.


2018/11/28: Early-Access Build 21 (2018/11/22). Small changes on the post, examples are re-run with the new build. JEP 334.

2018/11/14: JEP 230 added.

2018/10/08: JDK 12 Timeline added. JEP 340 and JEP 341 added. Early-Access Build 14 (2018/10/4).

2018/09/27: First time this post is published. Includes JEP 325 and 326. Early-Access Build 12 (2018/9/20).

Java 12 Features

The list is taken from the OpenJDK JDK 12 project page and the JEP Dashboard for JDK 12.

JEP 230: Microbenchmark Suite

A way, and a suite of microbenchmarks, to easily test the performance of JDK, based on Java Microbenchmark Harness (JMH) will be added to JDK source code.

It used like below, but these steps require you to have a system capable of building JDK from the source code.

$ cd jdk-src
$ sh make/devkit/createJMHBundle.sh
$ ./configure --with-jmh=build/jmh/jars --enable-headless-only
$ make test TEST="micro:java.lang.reflect"

... after many lines of output ...

Test selection 'micro:java.lang.reflect', will run:
* micro:java.lang.reflect

Running test 'micro:java.lang.reflect'
# JMH version: 1.21
# VM version: JDK 12-internal, OpenJDK 64-Bit Server VM, 12-internal+0-adhoc.ubuntu.jdk-src
# VM invoker: /home/ubuntu/jdk-src/build/linux-x86_64-server-release/images/jdk/bin/java
# VM options: --add-opens=java.base/java.io=ALL-UNNAMED
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.openjdk.bench.java.lang.reflect.Clazz.getConstructor

# Run progress: 0.00% complete, ETA 01:31:40
# Fork: 1 of 5
# Warmup Iteration   1: 19.849 ns/op
# Warmup Iteration   2: 19.067 ns/op
# Warmup Iteration   3: 20.044 ns/op
# Warmup Iteration   4: 20.050 ns/op
# Warmup Iteration   5: 20.061 ns/op
Iteration   1: 20.037 ns/op
Iteration   2: 20.019 ns/op
Iteration   3: 20.070 ns/op
Iteration   4: 20.052 ns/op
Iteration   5: 20.024 ns/op

.. and continues running many more tests

JEP 325: Switch Expressions

This is a preview feature.

There are two main changes to switch in Java with this JEP:

  • Introduction of case L -> syntax that removes the need for break statements, because only the statements next to -> is executed.
  • switch can be an expression, so it can have a value, or it can return a value.


public class JEP325 {

	public static void main(String[] args) {

    // args[0] is the day of week, starting from 1-sunday
    final int day = Integer.valueOf(args[0]);

    // traditional switch
    switch (day) {
      case 2: 
      case 3: 
      case 4: 
      case 5: 
      case 6: 
      case 7:
      case 1:

    // case L -> syntax
    // no break necessary, only code next to -> runs
    switch (day) {
      case 2, 3, 4, 5, 6 -> System.out.println("weekday");
      case 7, 1 -> System.out.println("weekend");
      default -> System.out.println("invalid");

    // switch expression
    // then switch should be exhaustive if used as expression
    // break <value_of_switch_expression> syntax for blocks
    final String attr = switch (day) {
      case 2, 3, 4, 5, 6 -> "weekday";
      case 7, 1 -> "weekend";
      // it is possible to do this without a block and break
      // so default -> "invalid"; is actually enough here
      default -> {
        break "invalid";




Depending on the arg[0], this outputs the same string (weekday, weekend or invalid) three times.

JEP 326: Raw String Literals

This is a preview feature.

Raw String Literals make it easy to use strings containing special characters and multi-line strings. Raw String Literals are created with backtick ` symbol. This JEP also introduces String::align function to make it easy to use multi-line indented text, and unescape/escape functions for conversions to/from (traditional) String Literals.


public class JEP326 {
  public static void main(String args[]) {

    // traditional string
    final String s1 = "test";
    // traditional multiline string
    final String s2 = "line1\nline2";

    // raw string literals
    final String rs1 = `test`;
    final String rs2 = `
    final String rs3 = ``backtick`inside``;
    final String rs4 = `\n`;


    // String::unescape() is not implemented yet on jdk12+21
    // System.out.println(rs4.unescape().length());



This outputs:




JEP 334: JVM Constants API

This JEP is proposed to target JDK 12. It is not yet integrated.

JEP 334 proposes an API modeling the key class-file and run-time artifacts such as constant pool. Such API will contain classes like ConstantDesc, ClassDesc, and the draft of this API is available here: https://cr.openjdk.java.net/~vromero/constant.api/javadoc.04/java/lang/invoke/constant/package-summary.html.

This will be useful for tools manipulating the classes and methods.

JEP 340: One AArch64 Port, Not Two

There are two different set of sources, thus ports, targeting ARM 64-bit in the JDK. One is contributed by Oracle, arm64 (hotspot/cpu/arm), and the other is aarch64 (hotspot/cpu/aarch64). This JEP removes arm64, thus all source code used with #ifdefs under hotspot/cpu/arm will be removed and 64-bit ARM build will be default to aarch64. hotspot/cpu/arm will still provide the 32-bit ARM port.

$ cd jdk-src/src/hotspot/cpu/arm
$ hg update jdk-12+1
$ grep -r AARCH64 * | wc -l
$ hg update jdk-12+21
$ grep -r AARCH64 * | wc -l

JEP 341: Default CDS Archives

Class Data-Sharing (CDS) is a feature to reduce startup time and benefit from memory sharing. However, if you do not install the JRE with the installer, the CDS archive is not generated by default and java -Xshare:dump has to be run manually.

This can be observed in JDK 11. If you install the JDK 11 GA Release from http://jdk.java.net/11/ , lib/server folder does not contain the CDS archive, classes.jsa file. If you run java -Xshare:dump, it will be generated.

With this JEP, CDS archive will be generated by default.

The best way to receive blog updates is to follow me on Twitter: @metebalci