Open In App

New Features of Java 12

Last Updated : 24 Jan, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Oracle released Java SE(Standard Edition) 12 on March 19, 2019, after which they plan to have a new release every six months. JDK 12 came with a lot of improvements over JDK 11. This latest version offers a list of new features such as Switch Expressions, Default CDS Archives, Shenandoah, Microbenchmark Suite, among others. These new features are discussed below.

1. Changes in Switch expressions:

Switch expressions will now be used as a statement as well as expressions. This makes code simplification and pattern matching possible for the switch.

  • In earlier versions, missing break statements resulted in default fall through which was error-prone.
  • The default case is mandatory in the switch expressions.

Now, the new Arrow syntax for switch introduced as  

case X -> {} 

Denotes that only if the label matches, statements on the right side of the arrow will be executed.

The Switch expressions of Java 11 and Java 12 can be compared as follows:

Java 11

Java




// Java program to demonstrate the
// classic switch statement
 
import java.io.*;
 
class Java11switchStatement {
 
    static int getMealNumber(String meal)
    {
        // stores mealNumber
        int mealNumber;
 
        // classic switch statement
        switch (meal) {
 
        case "SOUP":
            mealNumber = 1;
            break;
 
        case "BURGER":
 
        case "CHIPS":
 
        case "SANDWICH":
            mealNumber = 2;
            break;
 
        case "SPAGHETTI":
 
        case "MACARONI":
            mealNumber = 3;
            break;
 
        default:
            throw new IllegalStateException(
                "Cannot prepare " + meal);
        }
 
        return mealNumber;
    }
    public static void main(String[] args)
    {
 
        // define meal
        String meal = "BURGER";
 
        // print mealNumber
        System.out.println("The mealNumber is : "
                           + getMealNumber(meal));
    }
}


Output

The mealNumber is : 2

Java 12

Java




// Java program to demonstrate the
// new switch expression
 
import java.io.*;
 
class Java11switchStatement {
 
      // returns mealNumber
    static int getMealNumber(String meal)
    {
 
        // stores mealNumber using
        // new switch expression
        int mealNumber = switch (meal)
        {
 
           case "SOUP" -> 1;
 
           case "BURGER", "CHIPS", "SANDWICH" -> 2;
 
           case "SPAGHETTI", "MACARONI" -> 3;
             
           default -> throw new IllegalException("");
        }
 
        return mealNumber;
    }
   
    public static void main(String[] args)
    {
 
        // define meal
        String meal = "BURGER";
 
        // print mealNumber
        System.out.println("The mealNumber is : "
                           + getMealNumber(meal));
    }
}


Output

The mealNumber is : 2

2. Shenandoah (A new and improved Garbage Collector)

This is an experimental feature and introduces a new garbage collection (GC) algorithm, Shenandoah. It offers low pause time by concurrent execution of evacuation work with running Java threads. With this, pause times are independent of the heap size. For example, a 5MB heap will have the same pause time as that of a 10GB one.

3. JVM constants API: This API helps those programs that manipulate classes and methods. These programs need to model byte code instructions and handle loadable constants. Constants of the type String or Integer work fine. However, it becomes tricky with Constant type as Class. Loading classes can fail if Class is inaccessible or doesn’t exist. With the new API in place, interfaces such as ClassDesc, MethodTypeDesc, MethodHandleDesc, and DynamicConstantDesc, handle constant values symbolically thereby eliminating complexity. 

4. Abortable mixed collections for G1: The default garbage collector, Garbage First (G1), uses an analysis engine to determine the collection set and once the collection starts, all live objects should be collected without stopping. This results in exceeding the target pause time. To address this issue, G1 collection sets are made abortable by breaking the set into optional and mandatory parts. By prioritizing the mandatory set, the pause time target can be achieved often.  

5. Default CDS archives: A class data sharing (CDS) archive is created to make the JDK build process more efficient thereby improving the out-of-the-box startup time.

6. Microbenchmark suite: Developers can run existing or new benchmarks easily with the microbenchmark suite added to the JDK source code.

7. Promptly return unused committed memory from G1: With this improved feature, when G1 is idle, the garbage collector automatically returns unused heap memory to the operating system. This is done by concurrent checks of Java heap by G1.

8) Files.mismatch() method: This new method compares two files.  

Method Signature

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

Returns: -1L if no mismatch else Position of the first mismatch.

It returns the position of the mismatch in either of the two cases.

  • Case 1: if the size of the files does not match. Here, the size of the smaller file is returned.
  • Case 2: if the bytes does not match. Here, the first mismatching byte is returned.

Example:

Java




import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
 
public class FilesCompareExample {
 
    public static void main(String[] args)
        throws IOException
    {
        Path path1 = Files.createTempFile("file1", ".txt");
        Path path2 = Files.createTempFile("file2", ".txt");
        Files.writeString(path1, "Geeks for geeks");
        Files.writeString(path2, "Geeks for geeks");
 
        long mismatch1 = Files.mismatch(path1, path2);
 
        System.out.println(
            "File Mismatch position or -1 is returned if there is no mismatch");
 
        System.out.println(
            "Mismatch position in file1 and file2 is : "
            + mismatch1);
 
        path1.toFile().deleteOnExit();
        path2.toFile().deleteOnExit();
 
        System.out.println();
 
        Path path3 = Files.createTempFile("file3", ".txt");
        Path path4 = Files.createTempFile("file4", ".txt");
        Files.writeString(path3, "Geeks for geeks");
        Files.writeString(path4, "Geeks for the geeks");
 
        long mismatch2 = Files.mismatch(path3, path4);
 
        System.out.println(
            "Mismatch position in file3 and file4 is : "
            + mismatch2);
 
        path3.toFile().deleteOnExit();
        path4.toFile().deleteOnExit();
    }
}


 
Output

Mismatch position in file1 and file2 is : -1 
Mismatch position in file3 and file4 is : 10 

9) Compact Number Formatting: It is the formatting applied to general-purpose numbers e.g. decimal, currency, percentage to make them compact due to space constraint. In the below example, 1000 will be formatted as ‘1K’ in a short style and ‘1 thousand’ in a long style.

Java




import java.text.NumberFormat;
import java.util.Locale;
 
public class CompactFormatExample {
    public static void main(String[] args)
    {
        NumberFormat fmtLong
            = NumberFormat.getCompactNumberInstance(
                Locale.US, NumberFormat.Style.LONG);
 
        System.out.println(fmtLong.format(100));
        System.out.println(fmtLong.format(1000));
        System.out.println(fmtLong.format(10000));
 
        NumberFormat fmtShort
            = NumberFormat.getCompactNumberInstance(
                Locale.US, NumberFormat.Style.SHORT);
 
        System.out.println(fmtShort.format(100));
        System.out.println(fmtShort.format(1000));
        System.out.println(fmtShort.format(10000));
    }
}


Output

100
1 thousand
10 thousand
100
1K
10K

10) Teeing Collectors in Stream API: Collectors.teeing() is the new helper function that helps in performing two steps function into a single step. This results in less verbose code.

Method Signature

public static Collector teeing​ (Collector downstream1, Collector downstream2, BiFunction merger);

Here, we are performing two different stream operations on two different collectors and the result is merged using the supplied BiFunction.

Example:

Java




import java.io.*;
import java.util.*;
 
class TeeingCollectorsExample {
    public static void main(String[] args)
    {
        double mean
            = Stream.of(2, 3, 4, 5, 6)
                  .collect(Collectors.teeing(
                      summingDouble(i -> i), counting(),
                      (sum, n) -> sum / n));
 
        System.out.println(mean);
    }
}


Output

4.0

11) Java String New Methods: Java 12 introduced the following new methods in the String class:

i) indent(int n): It adjusts the indentation of each line of the given string based on the argument passed.

Based on the value of n passed, we can have the following cases :

  • If n > 0, spaces are inserted at beginning of each line
  • If n < 0, spaces are removed at the beginning of each line
  • If n < 0 and n < available white spaces, all leading spaces are removed
  • If n = 0, line remains unchanged
String str = "**********\n  Welcome\n  Good Morning\n**********";
System.out.println(str.indent(0));
System.out.println(str.indent(3));

Output

**********
  Welcome
  Good Morning
**********
   **********
     Welcome
     Good Morning
   **********
**********
Welcome
Good Morning
********** 

ii) transform(Function<? super String,​? extends R> f): It is used to call a function expecting a string argument and producing result R. 

String s = "Java,Python,Angular";
List result = s.transform(s1 -> {return Arrays.asList(s1.split(","));});
System.out.println(result);

Output

[Java, Python, Angular]

iii) Optional<String> describeConstable(): This method will return an Optional object containing a descriptor for the String instance.

String message = "Welcome!";
Optional<String> opOfMessage = message.describeConstable();
System.out.println(opOfMessage);

Output

Optional[Welcome!]

iv) String resolveConstantDesc​(MethodHandles.Lookup lookup): This method will return a String object which is the descriptor for the invoking String instance.

String message = "Welcome!";
String constantDesc = message.resolveConstantDesc(MethodHandles.lookup());
System.out.println(constantDesc);

Output

Welcome!

Though Java 12 is yet to gain popularity as compared to Java 8, still the addition of new features more frequently is making Java comparable with better features of other languages thus maintaining its popularity in the market. 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads