October 23, 2020

After Java 8: Part 5 — Java 12


In the previous article, we covered changes in Java 11. In this article, we will discuss changes in the language that came with version 12.

API Updates

New String Methods in preparation for raw strings

  • String::indent
public String indent​(int n)Adjusts the indentation of each line of this string based on the value of n, and normalizes line termination characters.Parameters:n - number of leading white space characters to add or remove
Returns:string with indentation adjusted and line endings normalized
  • String::transform
public  R transform​(FunctionString,​? extends R> f) This method allows the application of a function to this string. The function should expect a single String argument and produce an R result.
Any exception thrown by f() will be propagated to the caller.Type Parameters:R - class of the result
Parameters:f - functional interface to a apply
Returns:the result of applying the function to this string

Compact Number Format

NumberFormat shortNF = NumberFormat.getCompactNumberInstance()`
String short = shortNF.format(2000);
// prints 2k

Locale and decimals are configurable of course. Also, it is possible to create a custom compact number pattern.

The Teeing Collector

In short, Teeing Collector is a Collector that merges the results of two other collectors. Every element passed to the resulting collector is processed by both downstream collectors, then their results are merged using the specified merge function into the final result.

Stream numbers = Stream.of(1,2,3,4,5);
long avarage = numbers.collect(
		(sum, count) -> sum/count
//avarage ==> 3


Checks if two files are the same.
Files.mismatch(Path.of("/file1"), Path.of("/file1"))
This method returns -1 if files are identical. Otherwise, it returns the position of first mismatching byte, or the size of the smaller file (in bytes) when the files are different sizes and every byte of the smaller file is identical to the corresponding byte of the larger file.

Switch Expressions

Switch expressions are the first “preview feature” in Java.
Preview feature is a new concept introduced in Java 12. A preview language or VM feature is a new feature of the Java SE Platform that is fully specified, fully implemented, and yet impermanent. It is similar to incubator modules. The difference is that incubator modules are referring to new APIs while, as already stated, preview features refer to a new language or VM features.
Enable incubator modules flag: --add-modules jdk.incubator.httpclient
Enable preview features flag: --enable-preview
In IntelliJ this can be done on: file/project structure/project language level and preferences/.../java compiler/additional command line parameters

Note that, as stated, preview features are yet impermanent and can change.

Java Micro-benchmarking Harness JMH

It measures execution time for small code pieces. It can be used to compare alternatives or to prevent performance regressions.

Advantages of JMH compared to ancient System.currentTimeMillis approach:

  • JMH Handles JVM warm-up
  • Consistent reporting
  • Multithreading support

Possible pitfalls of using JMH:

  • Dead code elimination
  • Other compiler optimizations
  • Assumptions

JMH has been developed as part of open jdk long time ago. In Java 12, JDK team added JMH and created a set of around 100 testsuites in JDK, making JMH defacto standard micro-benchmarking suite.
Note that JMH is still a separate project. If you want to include it to your project have a look at:
Official project page
Example integration with spring boot

JVM Changes

G1 improvements

Promptly return unused committed memory. The main goal for this feature is to improve the G1 garbage collector to immediately return Java heap memory to the operating system when inactive. To achieve this goal G1 will during low application activity periodically generate or continue a concurrent cycle to check the complete Java heap usage.

This will trigger it to immediately return unused Java heap portions to the operating system. When under user control, there’s an option to perform a full GC to maximise the volume of memory returned.


Shenandoah is an experimental, low-pause-time garbage collector which targets large heap applications. It is contributed by Red Hat, and for some reason Oracle excludes it from their Open JDK build.
According to Red Hat, pause times are no longer in direct proportion with the size of the heap. In theory, this means that a heap that’s 2 GB could have the same pause time as a heap that’s 200 GB. You can read more about Shenandoah at

JVM Constants API

This is a Low-level JVM feature that can be helpful for tools that manipulate classes and methods.