Java 12, or more accurately the Java Development Kit (JDK) 12) was officially released by Oracle on the 19th March 2019. This blog post highlights the subset of new features in this next major release of Java that will be of most interest to enterprise Java developers, in terms of the Java language, the core library APIs and other JDK features. It also outlines the support & maintenance available for this new release, and how this might influence your decision on whether to adopt it in production.
Java 12 comes only six months after the previous major Java release (11), in accordance with Java’s still relatively new time-based release schedule this comes six months. A list of the full set of major changes, each of which is a Java Enhancement Proposal (JEP), can be found on the OpenJDK project’s JDK 12 web page. A more detailed list of changes, including removals and deprecations can be found in Oracle’s JDK 12 Release Note.
For Java developers interested in knowing what this new release offers in terms of everyday Java development, there are only a very small no. of changes of interest. Let’s start with what’s new in terms of updates to Java the language –
1) New Language Features
Java 12 only contains a preview (beta) release of a single new language feature.
1.1) Switch Expression (Preview Only)
From JDK 12 the switch statement has been enhanced to be an expression capable of evaluating the switch conditions and returning a result. This change is backwards compatible – existing code that uses switch as a statement continues to work in Java 12 without change.
The following example is taken from the enhancement’s JEP – JEP 325: Switch Expressions (Preview).
Pre Java 12 a switch statement to convert the day of the week to the length of the name of that day, might be implemented as follows –
int numLetters; switch (day) { case MONDAY: case FRIDAY: case SUNDAY: numLetters = 6; break; case TUESDAY: numLetters = 7; break; case THURSDAY: case SATURDAY: numLetters = 8; break; case WEDNESDAY: numLetters = 9; break; default: throw new IllegalStateException("Logic error. Unknown day [" + day + “]”.); }
In Java 12, the above switch statement can now be rewritten as an expression as follows –
int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; default -> throw new IllegalStateException("Huh? " + day); };
As shown above, the switch expression returns a result which means means it now only needs to be assigned to a variable once. The above example also illustrates some other significant improvements to the syntax of the switch statement –
- Removal of the need for each case to be specified separately. Cases that do the same thing (e.g. return the same value) can be specified in one case statement using comma separators.
- The “->” operator is used to provide a terser syntax for returning the result – a replacement for the switch statements assignment and break statement. (This is the same syntax as the operator used in Lambda expression. I’m not sure at this stage whether that’s a good thing or a little confusing).
This enhancement significantly reduces the verbosity (boilerplate) of writing the above type of switch statements. (In the example above the no. of lines of code is reduced from 20 to 7). However, more importantly, the switch expression is easier to read.
As noted above, this new language feature has only been released as a preview, to allow its broader evaluation and feedback. The API could be changed, or completely removed in a future release. Therefore it’s advisable not to rely on it in your production apps, yet.
2) Enhancements to the Standard Library APIs
A few minor enhancements have been made to the Java SE library APIs in JDK 12. Those that will be of most use in everyday development are outlined below.
2.1) Class java.lang.String
Adding to the enhancements that were in Java 11 (see my previous Java 11 new features blog post section “2.4.1) java.lang.String”), the String class has been further enhanced in JDK 12 to provide a couple more useful built-in string manipulation methods –
indent(int n) : String – Indents a string by adding a number of leading whitespace characters to the String. If the parameter is negative that number of leading whitespace characters will be removed (if possible).
transform(Function<? super String,? extends R> f) : R – Supports converting or mapping the String by applying a provided Function to it that returns a result of any type ‘R’. The result does not need to be another String.
2.2) Stream API
The Stream API has a new implementation of a java.util.stream.Collector (terminal reduction operation for accumulating a stream of values) that can be created using the java.util.stream.Collectors utility class’ new method Collectors.teeing() method.
The Javadoc of the aforementioned method indicates that the new “teeing” collector takes three arguments – two Collectors and a BiFunction. It behaves by passing all the values in the input stream on which it is invoked to both of the supplied “downstream” Collectors; then taking the (accumulated) result from each of these Collectors and passing them to the supplied BiFunction to reduce and generate the final result, i.e.
---> Collector arg 1 --- | | | ---> --- stream ---> BiFunction ---> Result | ---> | | ---> Collector arg 2 ---
Simon Ritter provides a code example of how the new Collector might be used in his more comprehensive article on changes in Java 12 – 39 New Features (and APIs) in JDK 12.
3) Other New JDK Features
This section outlines any other changes to the JDK, outside of the Java language and core libraries, that are of note for developers.
3.1) Microbenchmark Test Suite
The Java Microbenchmarking Harness (JMH) is an existing tool (test harness) for building, running, and accurately measuring the performance of Java apps (and other languages that run on the JVM), avoiding some common pitfalls and mistakes which can lead to inaccurate measurements.
JDK 12 includes an enhancement relating to the Java Microbenchmarking Harness as described in JEP 230: Microbenchmarking Suite. But It’s worth noting that this enhancement is only targeted at developers of the OpenJDK itself, with the aim of making it easier for them to performance test changes to OpenJDK using JMH. (It includes a source release of JMH in the OpenJDK, adds support for building JMH as part of the OpenJDK, and adds an initial set of JMH based tests for the JDK). In particular it does not mean that JDK 12 now includes a binary for the JMH tool in a similar way to javac etc. If you want to use JMH to performance test your own apps you still need to down and built it yourself as described in the aforementioned article.
In addition to the above, like other major releases JDK 12 will contain many additional bug fixes, and possibly some performance improvements.
4) Upgrade / Adoption Considerations
As I’ve mentioned for previous major releases of Java, there are several issues to consider before committing to using JDK 12 for your production apps, and if you do, also some planning considerations.
Firstly, before deciding to adopt JDK 12 in production, consider that Oracle have designated that it is not a long-term support (LTS) release. Whilst JDK 11, which is an LTS release, will continue to benefit from maintenance (bug fixes and security patches) from the Java community, and a choice of paid support, for several years to come yet, JDK 12 will not. When the next major release (13) of Java becomes available, which is scheduled to be in 6 months after JDK 12, in March 2020, Oracle and others will cease providing any further maintenance or offering support. So, if security and bug fixes are important to your business, either skip JDK 12 in production and stay on Java 11, or be ready to (re-test and) upgrade to JDK 13 as soon as it becomes available…
If you do decide to adopt JDK 12 in production, then you’ll need to check when the providers of all your dev tools (e.g. Gradle, Maven) and third party libraries (e.g. Spring framework, Jackson etc) have confirmed their software is compatible.
Even if you decide not to adopt JDK 12 in production you can still test whether your existing apps are compatible with it, potentially shortening the timeline for adopting the next LTS release (Java 17; currently scheduled for September 2021).
5) Conclusion
From the perspective of everyday Java development JDK/Java 12 doesn’t add much – it only contains a preview of a single new language feature (switch expressions) and a few core library features. Like other major Java releases it does however contain a number of fixes and possible runtime performance improvements for the JVM. But it is not a long-term support (LTS) release. Given all of this, my advice would be to defer adopting JDK 12 for your production apps, but to instead take it for a spin in test environments to check its compatible with your existing apps, and perhaps try out switch expressions.
Thanks.