Core Java

New Features in Java 12

Java 12, released in March 2019, introduced several features and enhancements. Let us delve into Java 12 new features.

1. Java 12 String Methods

The indent modifies the indentation of each line according to the provided integer parameter. When the parameter is positive, additional spaces are added at the start of each line. Conversely, if the parameter is negative, spaces are stripped from the beginning of each line. In cases where a particular line lacks adequate white space, all leading white space characters are eliminated.

  • n > 0: Insert space at the beginning of each line.
  • n < 0: Remove space at the beginning of each line.
  • n < 0 and n < available spaces: Remove all leading spaces of each line.
  • n = 0: No change.

Consider a simple example. Initially, we’ll indent the text using four spaces, and subsequently, we’ll eliminate the entire indentation.

public class IndentationExample {
    public static void main(String[] args) {
        String text = "Hello Baeldung!\nThis is Java 12 article.";

        // Indent with four spaces
        text = indentText(text, 4);
        System.out.println("After indenting with four spaces:");

        // Remove ten spaces from the beginning of each line
        text = indentText(text, -10);
        System.out.println("After removing ten spaces from the beginning of each line:");

    private static String indentText(String text, int spaces) {
        return switch (Integer.signum(spaces)) {
            case 1 -> text.indent(Math.abs(spaces));
            case -1 -> removeIndentation(text, Math.abs(spaces));
            default -> text; // No change for zero or other values

    private static String removeIndentation(String text, int spacesToRemove) {
        String[] lines = text.split("\\n");
        StringBuilder result = new StringBuilder();

        for (String line : lines) {
            if (line.length() >= spacesToRemove) {
                result.append(line, spacesToRemove, line.length());

        return result.toString();

2. Java 12 File::misMatch

This method is employed to compare two files and determine the position of the initial differing byte in their content. The result will fall within the inclusive range of 0L to the byte size of the smaller file or be -1L if the files are identical. It is represented by the following syntax –

public static long mismatch(Path path1, Path path2) throws IOException { … }

3. Java 12 Teeing Collector

In Java 12, a new method is introduced to Collectors that facilitates performing two distinct operations on a collection and subsequently merging the results. The syntax for the teeing method is as follows –

Collector<T, ?, R> teeing(
   Collector<? super T, ?, R1> downstream1,
   Collector<? super T, ?, R2> downstream2, 
   BiFunction<? super R1, ? super R2, R> merger

In this syntax, various operations are executed on a collection, and the results are subsequently combined using a merging BiFunction.

Consider a simple example.


public class AppTest {
    public static void main(String[] args) {
        double result = Stream.of(11,12, 13, 14, 15, 16, 17)
                        Collectors.summingDouble(i -> i),
                        (sum, count) -> sum / count
        System.out.println("Result: " + result);

4. Java 12 Compact Number Formatting

Java 12 introduces concise formatting, enabling the transformation of lengthy numbers, such as decimals, currency, or percentages, into abbreviated or expanded forms. The following syntax illustrates its usage −

public static NumberFormat getCompactNumberInstance(Locale locale, NumberFormat.Style formatStyle)

Consider a simple example.

import java.text.NumberFormat;
import java.util.Locale;

public class AppTest {
    public static void main(String[] args) {
        printCompactNumberFormat(NumberFormat.Style.LONG, 1000);
        printCompactNumberFormat(NumberFormat.Style.LONG, 1000000);

        printCompactNumberFormat(NumberFormat.Style.SHORT, 1000);
        printCompactNumberFormat(NumberFormat.Style.SHORT, 1000000);

    private static void printCompactNumberFormat(NumberFormat.Style style, long number) {
        NumberFormat formatter = NumberFormat.getCompactNumberInstance(Locale.US, style);
        String formattedNumber = formatter.format(number);

5. Java 12 Switch Expression (Preview)

Java 12 introduces expression support to the switch statement as a preview feature. The following modifications are introduced in the new switch with expressions:

  • No fallthrough.
  • No break statement is required to prevent fallthrough.
  • A single case can have multiple constant labels.
  • The default case is compulsory now.

Consider a simple example.

public class AppTest {

  public static void main(String[] args) {
    System.out.println("Old Switch");

    System.out.println("New Switch");

  public static void printDayTypeNewStyle(String day) {

  public static String getDayTypeNewStyle(String day) {
    return switch (day) {
    case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Weekday";
    case "Saturday", "Sunday" -> "Weekend";
    default -> "Invalid day.";

  public static void printDayType(String day) {

  public static String getDayTypeOldStyle(String day) {
    String result = null;
    switch (day) {
    case "Monday":
    case "Tuesday":
    case "Wednesday":
    case "Thursday":
    case "Friday":
      result = "Weekday";
    case "Saturday":
    case "Sunday":
      result = "Weekend";
      result = "Invalid day.";
    return result;

6. Java 12 Garbage Collection algorithms

Java 12 brings forth several improvements to its garbage collection algorithms.

  • JEP 189 – Shenandoah: A Low-Pause-Time Garbage Collector (Experimental): An experimental Low-Pause-Time Garbage Collector, Shenandoah, is introduced to reduce the GC pause time. It operates in parallel with running Java threads, reducing the dependency of GC on heap size and ensuring consistency. This improvement means that garbage collection pause time will be similar for both 2 MB and 2 GB heap space. Shenandoah is expected to become a part of the main Java release with Java 15.
  • JEP 346 – Promptly Return Unused Committed Memory: Java 12 introduces a feature where G1 will process Java heap space if the application is inactive, releasing memory back to the operating system. This preemptive behavior conserves and frees up memory.
  • JEP 344: Abortable Mixed Collections: Java 12 enhances G1 efficiency by introducing abortable mixed collections. If these collections exceed the defined pause limit, they can be aborted. Mixed collections are now categorized as mandatory and optional. G1 collectors can prioritize mandatory sets to check the pause time goal.

7. Conclusion

Java 12, released in March 2019, brought forth several notable features and enhancements, showcasing the ongoing commitment of the Java community to improve the language. The introduction of switch expressions, a preview of Shenandoah as an experimental garbage collector, and enhancements to existing collectors underscored Java 12’s focus on enhancing developer productivity and runtime performance. Additionally, the prompt release of Java 12, following the new time-driven release model, demonstrated the agility of the Java development process. While each Java version continues to build on the strengths of its predecessors, Java 12 stands as a testament to the Java community’s dedication to innovation, evolution, and meeting the needs of modern software development. Developers are encouraged to explore these new features and consider their adoption based on project requirements and compatibility considerations. As Java continues to evolve, the advancements introduced in Java 12 pave the way for a more efficient and feature-rich programming environment.


An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Notify of

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

Inline Feedbacks
View all comments
Back to top button