Available since March 19th, 2019, Java 12 is yet another small step forward for Java. It should be noted that Java 12 is not a LTS version (Long Term Support) as is Java 11 and will be Java 17 (as seen in this previous article to better understand the release cycle imposed by Oracle), so it includes a limited number of novelties and if you do not have any particular interest for one of them, it is better to wait a little before using it in order to pass the pitfalls of  “early” releases.

In this article introducing Java 12’s new features, we have decided to select the ones that will be most useful to you in your everyday tasks or that will help you in anticipating the future. We will first see an improvement in the switch functionality in preview mode, then some improvements in memory and Garbage Collector and finally other improvements considered minor.

Editing Switch Expressions

The Switch Expressions syntax has been lightened in preview mode (see this link to enable preview mode for compile and run times with –enable-preview). While the old version was read from top to bottom, each box is now encapsulated, so no more problems if you forgot a break. A simple example should make it clearer. Take the example of a ‘to do-list’ with the activities to be done every day:

Before Java 12, we wrote:

switch(jour)
{
  case LUNDI :
    faireLesCourses() ; 
case MERCREDI :  
sortirLesPoubelles() ; 
   break ; 
case MARDI : 
  entrainementFoot() ; 
break ; 
case VENDREDI : 
  peuPasJaiPiscine() ;
  break ; 
case SAMEDI : 
case DIMANCHE : 
  weekend() ;
break ;  
default : 
  System.out.println(“Rien a faire le jeudi !”)

With Java 12, we can write:

switch(jour)
{  
case LUNDI, MERCREDI -> sortirLesPoubelles() ; 
case LUNDI -> faireLesCourses() ; 
case MARDI -> entrainementFoot() ; 
case VENDREDI -> peuPasJaiPiscine() ;
case SAMEDI, DIMANCHE -> weekend() ;
default  -> System.out.println(“Rien a faire le jeudi !”)
}

In addition, if we use a finite value object type as enums are, if all cases are covered, there is no need to mention default behavior.

Another point to emphasize, as each box now encapsulates its own local environment, we no longer have the problem with variable names:

Before Java 12:

switch (jour) {
        case LUNDI:
            int temp = ...
            break;
        case MARDI : 
            int temp2 = ...     // Ne peut pas être nommé temp
        case MERCREDI :
            int temp3 = ...     // Ne peut pas être nommé temp ou temp2
    }

With Java 12:

switch (jour) {
        case LUNDI ->
            int temp = ...
            break;
        case MARDI -> 
            int temp = ...     // Ca ne cause pas problème
        case MERCREDI ->
            int temp = ...     // Ca ne cause toujours pas de problème
    }

It is also possible to directly extract a value from its enum, which allows us to do this:

int nombreLettre = switch(jour) {
  case LUNDI, MARDI, JEUDI -> 5 ; 
  case MERCREDI, VENDREDI, DIMANCHE-> 8 ; 
  case SAMEDI-> 6 ;  
}

We hope that this evolution will be preserved in future versions of Java.

Memory and Garbage Collector Optimization

Java 12 brings several new features concerning the Garbage Collector, to the table. We will list and explain them below.

Concurrent Class Unloading

The garbage collector can now free memory space from unused classes and reduce the memory footprint of the application. This feature is enabled by default, but can be controlled with the -XX: -ClassUnloading option.

Shenandoah: A Low-Break-Time Garbage Collector

Java 12, also marks the arrival at the experimental stage of Shenandoah, a garbage collector created by RedHat and already implemented in aarch64 and amd64. It reduces GC break times by enabling garbage collection at the same time as program execution. The size of the heap therefore no longer has a direct impact on the breaks. It can therefore be useful for applications for which it is advantageous to limit the response and pause times but is not preferred if one seeks a low memory footprint and optimize the processing speed. It should be noted that this feature is still experimental, so in order to use it you will have to activate these two flags: -XX: + UnlockExperimentalVMOptions and -XX: + UseShenandoahGC.

However, this feature is not integrated into the default build of openJDK, so you will have to go through another build or add it yourself to your own build. Moreover, it is not exclusive to java 12 despite the fact that it is developed in parallel with this version. Indeed it is possible to use Shenandoah, on Java 8, as well as 11 beforehand. You will find more information about the installation here.

Allocation of old generation Java heap on alternate memory devices

In an effort to take advantage of cheaper NV-DIMM memory systems, the Java team decided to test-use this type of memory in tandem with DRAM. Adding a flag -XX: AllocateOldGenAt = <path> allows you to specify a path to a directory (being the way the operating system exposes its NV-DIMM memory) to allocate old generation objects to it. The young generation objects are always allocated in the DRAM, and will be copied to this memory space as they evolve into the old generation.

Still in its experimental phase, this option is not yet useful as such, and remains a test that theoretically could free you a bit of your DRAM in exchange for a minimum slowdown (if your SSD or other type of memory is fast enough).

Other improvements in Java 12

Improved CoreSupport of Unicode

Evolution from Unicode 10.0.0 to Unicode 11.0.0, which allows something like Emoji, half stars for rating: JDK-8209923

Compact Number

With the Style.SHORT option it is possible to show figures in a readable way: JDK-8177552

NumberFormat fmt =  umberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
String result = fmt.format(1000); // = “1K”
String result = fmt.format(1000000 ); // = “1M”

Setting up the JVM: debugging and performance

More complete error report

You can add the flag -XX + ExtensiveErrorReports. It is then disabled by default.

Disabling security

Ability to disable (java.security.manager) for performance gains.

Default activation of CDS archives

The CDS archives allow memory sharing that speeds up the boot speed. However, if the JRE was not installed through the installer, this archive was not generated and it had to be regenerated manually via java -Xshare: dump. This feature is now enabled by default.

Goodbye for now: the raw string literals

A raw string literal opens with a sequence of one or more backticks (`). It closes when a sequence of joined backticks of equal length is encountered. Any other sequence is treated as part of the body of the chain.

In particular, it makes some text easier to write and read.

For example this text:

String unTest = `` Hello World\n\W\b /
                Ceci est un ` test
              ``;

Already present in several languages ​​such as C #, C ++ and Python, the JAVA team decided to add this feature for the release of Java 12. However, no viable solution was found for this version. If this feature interests you, know that it is very likely that we find it in the next iteration.

And now, we hope that this selection on the novelties of Java 12 will have teased your curiosity. To find them in global, do not hesitate in reading the Java 12 ’s release note below. We’ll meet again for Java 13!

REF: https://www.oracle.com/technetwork/java/javase/12-relnote-issues-5211422.html#NewFeature