New Features in Java 14

Java 14 has gone to General availability on 17th March, Let’s start with the Java 14 release schedule and then explore each of the features & enhancements at a high level.

Release Schedule:

2019/12/12 -Rampdown Phase One (fork from main line)
2020/01/16 -Rampdown Phase Two
2020/02/06 -Initial Release Candidate
2020/02/20 -Final Release Candidate
2020/03/17 -General Availability

New Features in Java 14:

1) Records (Preview) -JEP 359
2) Helpful NullPointerExceptions -JEP 358
3) Pattern Matching for instanceof (Preview) -JEP 305
4) Text Blocks (Second Preview)-JEP 368
5) Switch Expressions (Standard) -JEP 361
6) Packaging Tool (Incubator) -JEP 343
7) Foreign-Memory Access API (Incubator) -JEP 370
8) JFR Event Streaming -JEP 349
9) NUMA-Aware Memory Allocation for G1 -JEP 345
10) Non-Volatile Mapped Byte Buffers -JEP 352
11) Deprecate the Solaris and SPARC Ports -JEP 362
12) Remove the Concurrent Mark Sweep(CMS)Garbage Collector-JEP 363
13) ZGC on macOS -JEP 364
14) ZGC on Windows -JEP 365
15) Deprecate the ParallelScavenge + SerialOld GC Combination -JEP 366
16) Remove the Pack200 Tools and API -JEP 367

Note: To use the preview features available in the jdk use –enable-preview option to enable

1) Records (Preview):

With jdk14 we see a new enhancement “Records” to the java programming language. The main motive of records is to represent data as data. today classes are the carrier to hold the data to write a data carrier class properly, one has to write a lot of low-value, repetitive, error-prone code like constructors, accessors, equals(), hashCode(), toString(), setters, and getters, etc. Developers are often tempted to ignore these important methods which can lead to surprising behavior or poor debuggability. Of course, we have IDE’s which can help developers in generating this boilerplate code with a huge line of code seating in your java code. The real intention of the developer was to have just a place holder /carrier to hold the data, but not to write huge lines of repetitive code to access the data. To solve this problem records come into play its like enum in a form of classes. It’s not a replacement of class but its like modeling data as data in an easy, clear, and concise well-behaved nominal data aggregates.

A record has a name and a state description. The state description declares the components of the record. Optionally, a record has a body. For example:

RecordDeclaration:

{ClassModifier} record TypeIdentifier [TypeParameters]
(RecordComponents) [SuperInterfaces] [RecordBody]

The java compiler will generate all the necessary repetitive methods for you by default like constructs, equals(), hashcode(), toString and also accessors methods to get the fields.

you can have your own additional fields, methods and constructor. Records come with some default behavior and Restrictions

Default behavior:
-> Record fields are private and final
-> A read accessor method for each method parameter
-> public constructor, whose signature is the same as method signature
-> Default method implementation of equals, hash code, toString.

Restrictions:
-> Record is final class and can’t be abstract
-> Record can’t extend a class nor it can be extended by another class .
-> can’t declare instance fields other than the private final fields
-> Any other fields which are declared must be static
-> Record can’t extend another record .Every record by default is extended by java.lang.Record

Beyond the restrictions above, records behave like normal classes
-> They are instantiated via the new keyword like classes.
-> They can implement interfaces
-> Records can have additional fields, methods and constructs and you can override the default behavior
-> Declaration annotations are permitted on record if they are applicable to record components, parameters, fields, or methods
-> java.lang.Class is added with 2 new methods for the records
RecordComponent[] getRecordComponents()-> which tells list of methods
boolean isRecord() -> tells whether the class is record or not

2) Helpful NullPointerExceptions:

Every java developer would have encountered this exception during there time with java coding and finding out the exact cause for Null Pointer Exceptions(NPEs) some times becomes a nightmare, As it can occur almost anywhere in a program it is generally impractical to attempt to catch and recover from them. Today developers relay on the message thrown by JVM which consisting of a method, filename, and line number that caused the NPE which doesn’t state the exact root cause for null. For example, consider the below program

The exception is thrown here by JVM today just specifies the line number like below, which is not helpful wherein the above condition null pointer can occur for many reasons like object null or one of the getter methods returning null. Today developers used to debug each case by case to figure out the root cause for NPEs

With jdk14 the JVM will provide you with the exact root cause like below. By default the jdk14 is not enabled to show this exception you need to turn on -XX:+ShowCodeDetailsInExceptionMessages JVM option, with jdk15 this setting is turned on by default.

3) Pattern Matching for instanceof (Preview):
instanceof Operator has been used by most of java developers to check the type of instance before performing any further operation on it like casting or calling any methods in that.

Three things are going on here: a test (is obj a String?), a conversion (casting obj to String), and the declaration of a new local variable (s).we can see here boilerplate code been generated as we increase the checks, but what we need here was to just check the type and perform further operation. In jdk14 this has been simplified, with Pattern matching it allows the desired ‘shape’ of an object to be expressed concisely (the pattern), and for various statements and expressions to test that ‘shape’ against their input (the matching)

4) Text Blocks (Second Preview):
Text Blocks was firstly introduced in jdk13. A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired. with jdk14 we have 2 new escape sequences
-> Backslash (\) for line-terminator.
-> \s for line-terminator with preserving all the spaces present before, if not specified by default compiler used to ignored spaces.

for more detail explanation of text blocks in jdk13

5) Switch Expressions (Standard):
With jdk14 switch expression is now available as standard, in jdk12 and jdk13 this was available as preview version

jdk12 (initial preview) — Introduction of switch expression with lambda syntax allowing to specify multiple cases as expressions
jdk13 (Second preview) — Introduction of Yield statement in the place break, where Yield used to break the switch and return value.
jdk14 — Switch Expression as Standard.
for more detail explanation of Switch Expression

6) Packaging Tool (Incubator):
packaging tool is in Incubator module, the motivation of having packaging tool is to have Java applications packaged like installers according to the platform, for windows its.exe where the java application can be installed by just double-clicking on the installer, it gives end users a natural installation experience. This packaging is supported with JavaFX based javapackager tool “jpackage”. The supported formats for windows- exe, msi, for macOS — pkg, dmg and for Linux- deb, rpm .The installer comes with its own JVM and all required runtime artifacts where it can execute in a system where java was not available. For more options and its usage use jpackag --help

7) Foreign-Memory Access API (Incubator):
Today we have many java libraries and programs that access foreign memory, libraries like Ignite, mapDB, Memcached, and Netty’s ByteBuf API are used to Avoid the cost and unpredictability associated with garbage collection especially when maintaining large caches, Sharing memory across multiple processes.we have api’s in java.nio.ByteBuffer and sun.misc.Unsafe, yet till today we don’t have a java api that provides a satisfactory solution for accessing foreign memory. when it comes to accessing foreign memory, developers are faced with a dilemma: Should they use a safe but limited (and possibly less efficient) path (e.g., ByteBuffer), or should they abandon safety guarantees and embrace the unsupported and dangerous Unsafe API.

with jdk14 we now have a safe and efficient foreign-memory access api’s, Now developers will be freed of the limitations and dangers of existing APIs. They will also enjoy improved performance since the new API will be designed from the ground up with JIT optimizations in mind. This api’s are available under jdk.incubator.foreign package.The foreign-memory access API introduces three main abstractions:

MemorySegment -> used to model a contiguous memory region with given spatial and temporal bounds
MemoryAddress -> can be thought of as an offset within a segment
MemoryLayout -> is a programmatic description of a memory segment’s contents.

Memory segments can be created from a variety of sources, such as native memory buffers, Java arrays, and byte buffers (either direct or heap-based). For instance, a native memory segment can be created as follows:

This will create a memory segment that is associated with a native memory buffer whose size is 1000 bytes.

8) JFR Event Streaming:
Today Java Flight Recorder(JFR)which is used to monitor your VM provides 500 data points, most of them not available for you instantly but can be derived through other means by parsing log files generated. today, a user must start a recording, stop it, dump the contents to disk and then parse the recording file. This works well for application profiling, where typically at least a minute of data is being recorded at a time, but not for monitoring purposes. An example of monitoring usage is a dashboard that displays dynamic updates to the data. If there were a way to read data being recorded from the disk repository without creating a new recording file, much of this overhead could be avoided.

with jdk 14 we have api’s under the module jdk.jfr for the continuous consumption of JFR data on disk, both for in-process and out-of-process applications

9) NUMA-Aware Memory Allocation for G1:
Improve G1 performance on large machines by implementing NUMA-aware memory allocation. Modern multi-socket machines increasingly have non-uniform memory access (NUMA), that is, memory is not equidistant from every socket or core. Memory accesses between sockets have different performance characteristics, with access to more-distant sockets typically having more latency. if the -XX:+UseNUMA JVM option is specified when the JVM is initialized, the regions will be evenly spread across the total number of available NUMA nodes.

10) Non-Volatile Mapped Byte Buffers:
with this release MappedByteBuffer upgraded to access Non-volatile Memory (NVM) for storing the data permanently. The module jdk.nio.mapmode can be used to create the MappedByteBuffer (for read-write or read-only), which is mapped via a file on an NVC.

11) Deprecate the Solaris and SPARC Ports:
with jdk14 the Solaris/SPARC, Solaris/x64, and Linux/SPARC ports are deprecated with the intent to remove them in a future release. Dropping support for these ports will enable contributors in the OpenJDK Community to accelerate the development of new features that will move the platform forward.

12) Remove the Concurrent Mark Sweep (CMS) Garbage Collector:
In the release jdk14 the Concurrent Mark Sweep (CMS) Garbage Collector has been removed permanently, it was deprecated from jdk9 .with the introduction of some new GC’s in java the old GC are been removed and with this -XX:+UseConcMarkSweepGC jvm option is no more valid. Users can move to the G1 garbage collector or any of the other collectors. In older versions of java, CMS GC is not removed.

13, 14) ZGC on macOS & windows:
ZGC is a low-latency Garbage collector that was initially available in jdk11 and was only supported on Linux .now it has been supported on macOS & windows in Experimental mode.

15) Deprecate the ParallelScavenge + SerialOld GC Combination:
There is one combination of GC algorithms which is very little used but requires a significant amount of maintenance effort from jdk stand. The pairing of the parallel young generation GC (called ParallelScavenge) and the serial old GC (called SerialOld) this combination must be specifically enabled by the user with the -XX:+UseParallelGC -XX:-UseParallelOldGC command-line options. With this release, this has been deprecated and will be removed in future releases.

16) Remove the Pack200 Tools and API:
Pack200 Tool is a compression scheme for JAR files that are used to compress the jars. It was introduced in Java 5.0 by JSR 200. Its goal is “to decrease disk and bandwidth requirements for Java application packaging, transmission, and delivery.” Developers use a pair of tools — pack200 and unpack200 — to compress and uncompress their JAR files. An API is available in the java.util.jar package. This was introduced in a time where the transmission speed was very low over 56k modems. This was deprecated in jdk11 and with this release its been completely removed from the java.util.jar package.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store