What's New In JDK 14 Release

Introduction

 
Java has been  popular among developers from the beginning and is the most common coding language and application platform in the world. Currently Oracle has released the new Java SE version 14 and its developement kit JDK 14. Well there were some features introduced in Java 12, and Java 13 now has been enhanced in this version. (Although this version is not LTS.)
 
A significant number of Java Enhancement Proposals (JEPs) have been released in version 14. (Even more JEPs than Java 12 and 13 combined). According to Oracle there are a total of  16 enhancements/changes so far in this release.
 
Let's see these enhancements/changes as listed below.
  • Pattern Matching for instanceof (Preview)
  • Non-Volatile Mapped Byte Buffers (Incubator)
  • Helpful NullPointerExceptions
  • Switch Expressions (Standard)
  • Packaging Tool (Incubator)
  • NUMA-Aware Memory Allocation for G1
  • JFR Event Streaming
  • Records (Preview)
  • Deprecate the Solaris and SPARC Ports
  • Remove the Concurrent Mark Sweep (CMS) Garbage Collector
  • ZGC on macOS (experimental)
  • ZGC on Windows (experimental)
  • Deprecate the ParallelScavenge + SerialOld GC Combination
  • Remove the Pack200 Tools and API
  • Text Blocks (Second Preview)
  • Foreign-Memory Access API (Incubator)

Pattern Matching for instanceof

 
As we all know the use of instanceof operator  is used to check the object reference and given instance is of a particular type. It returns boolean type as a result.
 
Now in the current release the instanceof is enhanced to work with pattern matcher scenario. Pattern matching allows for the more clear and efficient expression of common logic in a system, namely the conditional removal of components from objects.
 
Before Java 14
  1. if (obj instanceof String) {  
  2. String str = (String) obj; // need to declare and cast again the object  
  3. .. str.contains(..) ..  
  4. }else{  
  5. str = ....  
  6. }  
Java 14 enhancements
  1. if (!(obj instanceof String str)) {  
  2. .. str.contains(..) .. // no need to declare str object again with casting  
  3. else {  
  4. .. str....  
  5. }  

Non-Volatile Mapped Byte Buffers

 
FileChannel API can be used to create MappedByteBuffer instances that refer to non-volatile memory.
 
JEP proposed an enhancement to this API called Path. Path is the interface that replaces java.io.File class as the representation of a file or a directory when we work in Java NIO. It's an enhancement to store MappedByteBuffer to load the portion of file data into non volatile memory[NVM] that can't be erased when power disrupts or in a shutdown state.
 
The only API change required is a new enumeration employed by FileChannel clients to request mapping of a file located on an NVM-backed file system rather than a conventional file storage system.
 

Risks and Assumptions

 
This implementation allows for management of NVM as an off-heap resource via a ByteBuffer. NVM also stores the metadata of JVM and with this proposed implementation it will hold the file data. This may rise to a compatiblity issue or incompatible if used in combination.
 
The proposed API can only deal with mapped regions up to 2GB. It may be necessary to revise the proposed implementation so that it
conforms to changes proposed in JDK-8180628 to overcome this restriction.
 
Helpful NullPointerExceptions
 
Every Java developer has a nightmare with NullPointerException, it arises every time when object get null. Well the proposed enhancement is an improvement in the NullPointerExceptions exception message generated by JVM. It will be helpful information to developers and support staff about the premature termination of a program.
 
For example, suppose an NPE occurs in this code:
  1. a.i = 99;  
The JVM will print out the method, filename, and line number that caused the NPE:
  1. Exception in thread "main" java.lang.NullPointerException  
  2. at Prog.main(Prog.java:5)  
Suppose an NPE occurs in this code:
  1. a.b.c.i = 99;  
Traditionaly the filename and line number do not tell exactly which variable was null. Was it a or b or c?
 
Now JDK14 JEP has improved this exception to be thrown as given below to know exactly which variable was null.
  1. Exception in thread "main" java.lang.NullPointerException:  
  2. Cannot read field 'c' because 'a.b' is null.  
  3. at Prog.main(Prog.java:5)  
Now that's good to know the culprit which is causing the NullPointerException.
 

Risks and Assumptions

 
Well the current message shows the details of variables and it will shows the variables from the source code as well. This might affect the performance because of the accessing of variables from debugging the file via reflection. This might be a security risk involved in this approach.
 
Switch Expressions (Standard)
 
We all know that Switch were statements but from the jdk 12 preview features Switch becomes the expression and can return a value now.
Let see an example to explore that.
  
Before Java 14:
  1. switch (day) {  
  2.    case MONDAY:  
  3.    case FRIDAY:  
  4.    case SUNDAY:  
  5.    System.out.println(6);  
  6.    break;  
  7.    case TUESDAY:  
  8.    System.out.println(7);  
  9.    break;  
  10.    case THURSDAY:  
  11.    case SATURDAY:  
  12.    System.out.println(8);  
  13.    break;  
  14.    case WEDNESDAY:  
  15.    System.out.println(9);  
  16.    break;  
  17. }  
Java 14 enhancements.
  1. switch (day) {  
  2.    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);  
  3.    case TUESDAY -> System.out.println(7);  
  4.    case THURSDAY, SATURDAY -> System.out.println(8);  
  5.    case WEDNESDAY -> System.out.println(9);  
  6. }  
Note
Arrow cases introduced the statements followed by arrow (->) executed.

Example - Returning a value.
 
Before Java 14
  1. int numLetters;  
  2. switch (day) {  
  3.  case MONDAY:  
  4.  case FRIDAY:  
  5.  case SUNDAY:  
  6.   numLetters = 6;  
  7.   break;  
  8.  case TUESDAY:  
  9.   numLetters = 7;  
  10.   break;  
  11.  case THURSDAY:  
  12.  case SATURDAY:  
  13.   numLetters = 8;  
  14.   break;  
  15.  case WEDNESDAY:  
  16.   numLetters = 9;  
  17.   break;  
  18.  default:  
  19.   throw new IllegalStateException("Wat: " + day);  
  20. }  
Java 14 enhancements in this regard.
  1. int numLetters =  
  2.  switch (day) {  
  3.   case MONDAY, FRIDAY, SUNDAY -> 6;  
  4.   case TUESDAY -> 7;  
  5.   case THURSDAY, SATURDAY -> 8;  
  6.   case WEDNESDAY -> 9;  
  7.  };  
Example - Yeilding a result
  1. //Arrow labels  
  2. static void grade(int g) {  
  3.   System.out.println(  
  4.    switch (g) {  
  5.     case 1 -> "A";  
  6.     case 2 -> "B";  
  7.     default -> "C";  
  8.    }  
  9.   );  
  10.  }  
  11.  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  
  12. //Yielding a value - introduce a new yield  
  13. int j =  
  14.  switch (day) {  
  15.   case MONDAY -> 0;  
  16.   case TUESDAY -> 1;  
  17.   default -> {  
  18.    int d = day.toString().length();  
  19.    int result = f(d);  
  20.    yield result;  
  21.   }  
  22.  };  
For more about this feature you can learn here (https://www.c-sharpcorner.com/article/Run-Java-Code-In-Visual-Studio-Code/) with fully functional code.

Packaging Tool (Incubator)

 
As the name suggests the packaging options is a packaging feature designed to ease the intallation process. A packaging tool can also help fill gaps left by other technologies such as Java Web Start, which was removed from Oracle’s JDK 11, and pack200, which was deprecated in JDK 11 for removal in a future release.
 
What we expect from a packaging tool is that it packages the jar files such a way that for different platform it behaves accordingly. 
 
For example, for a windows user there will be an .exe file. User might want to just double click the file and get it installed. A Mac oS user want just to double click .dmg file and drag it to the application folder. So the main goal is to make a better packaging tool which packages the  application code to the desired platform.
 
The supported platform-specific package formats are:
  • Linux: deb and rpm
  • macOS: pkg and dmg
  • Windows: msi and exe
By default, jpackage produces a package in the format most appropriate for the system on which it is run.
 
Records (Preview)
 
This is a preview language feature in JDK 14. It is used to compact the class declaration syntax with record. Traditionally we write additional code to make class fully functional like getter and setter methods, equals, hashcode etc.
 
By using this feature simply put record keyword before class then it will understand to include all necessarily details.
 
Example
 
Before Java 14:
  1. final class Point {  
  2.  public final int x;  
  3.  public final int y;  
  4.   
  5.  public Point(int x, int y) {  
  6.   this.x = x;  
  7.   this.y = y;  
  8.  }  
  9.   
  10.  // state-based implementations of equals, hashCode, toString  
  11.  // nothing else  
  12. }  
Java 14 with records
  1. record Point(int x, int y) { }  
Limitations using record
  • Records cannot extend any other class, and cannot declare instance fields other than the private final fields which correspond to components of the state description.
  • The components of a record are implicitly final.
  • A record's API is entirely defined by its state definition and cannot be modified by another class or record later.

Deprecate the Solaris and SPARC Ports

 
Oracle has deprecated Solaris / SPARC, Solaris / x64, and Linux / SPARC ports in order to remove them in the future. Oracle thinks that dropping these ports will accelerate in development of new features of OpenJdk.
 
Build-configuration changes
 
The following should result in an attempt to configure a Solaris and/or SPARC
  1. $ bash ./configure  
  2. ...  
  3. checking compilation type... native  
  4. configure: error: The Solaris and SPARC ports are deprecated and may be removed in a future release. \  
  5. Use --enable-deprecated-ports=yes to suppress this error.  
  6. configure exiting with result code 1  
  7. $  
The new --enable-deprecated-ports=yes configuration option will suppress the error and proceed.
  1. $ bash ./configure --enable-deprecated-ports=yes  
  2. ...  
  3. checking compilation type... native  
  4. configure: WARNING: The Solaris and SPARC ports are deprecated and may be removed in a future release.  
  5. ...  
  6. Build performance summary:  
  7. * Cores to use:   32  
  8. * Memory limit:   96601 MB  
As we can see that when you will use this configuration and configure a build for Solaris and SPARC (including Solaris / SPARC, Solaris / x64, Linux / SPARC) we will issue the error / warning.
 

Remove the Concurrent Mark Sweep (CMS) Garbage Collector

 
JEP proposed to remove the concurrent mark sweep (CMS) garbage collector because oracle has already introduced ZGC and Shenandoah, along with further improvements to G1, which has been the intended successor to CMS since JDK 6.
 
The following warning message will result in the attempt to use CMS via the -XX:+UseConcMarkSweepGC option
  1. Java HotSpot(TM) 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; \  
  2. support was removed in <version>  

Text Blocks (Second Preview)

 
Prior to Java 14 it was very difficult to read the embedded HTML, JSON, XML etc. because of various "" and + signs. Now to overcome this problem Oracle has introduced the text blocks for better readablity and maintainblity.
 
A text block contains zero or more content characters, which are enclosed by open and close delimiters.
 
HTML Example Without Text Block
  1. String html = "<html>\n" +  
  2.               "    <body>\n" +  
  3.               "        <p>Hello, world</p>\n" +  
  4.               "    </body>\n" +  
  5.               "</html>\n";  
A text block is a multi-line string literal which prevents the need for most escape sequences, formats the string automatically, and  gives the developer the control to format the string if necessary.
 
Enhancement in java 14 : Text blocks
  1. String html = """  
  2.               <html>  
  3.                   <body>  
  4.                       <p>Hello, world</p>  
  5.                   </body>  
  6.               </html>  
  7.               """;  
We can see the beauty  -- all the escape sequences are gone with + sign and various "" are not there. Only text in the """ is looking so neat and clean. In early 2019, JEP 355 proposed text blocks as a follow-up to the JEP 326 (Raw String literals) exploration, which had been withdrawn.
 
Two new escape sequences in Java 14. 
 
Two new escape sequences are newlines (line-terminator) denoted by \ and the second is for white space (single space) denoted by /s.
 
Newlines Example
  1. // Without Text Block  
  2. String literal = "two escape sequences first is for newlines " +  
  3. "and, second is to signify white space " +  
  4. "or single space.";  
  5.   
  6. // With the \<line-terminator> escape sequence this could be expressed as:  
  7. String text = """  
  8.                 two escape sequences first is for newlines \  
  9.                 and, second is to signify white space \  
  10.                 or single space.\  
  11.                 """;  
Here we can see that string breaking is denoted by \ ie. line terminator,  which becomes more readable and maintainable.
 
White Space or Single Space Example
  1. // Using \s at the end of each line in this example guarantees that each line is exactly six characters long  
  2. String colors = """  
  3.     aaa\s  
  4.     bbb\s  
  5.     ccc\s  
  6.     """;  
Here \s denotes the single white space and guarantees that each line is exactly six characters long. The \s escape sequence can be used in both text blocks and traditional string literals.
 
The following methods will be added to support text blocks;
  • String::stripIndent(): used to strip away incidental white space from the text block content
  • String::translateEscapes(): used to translate escape sequences
  • String::formatted(Object... args): simplify value substitution in the text block
ZGC on macOS : JEP 364
 
Enhancement has been done for macOs as well.  It ports the ZGC garbage collector to macOS. Part of the JEP is also the collector's functionality for freeing unused device memory.
 
The tests that usually run for ZGC on Linux, will be run for macOS too.
  • Support for multi-mapping memory on macOS.
  • Support in ZGC for discontiguous memory reservations.
ZGC garbage collector on Windows : JEP 365
 
As per JEP recommendation the Windows implementation of ZGC requires the following work:
  • Support for multi-mapping memory
  • Support for mapping paging-file backed memory into a reserved address space. 
  • Support for mapping and unmapping arbitrary parts of the heap
  • Support for committing and uncommitting arbitrary parts of the heap.