New Features in Java 14
Java 14, released in March 2020, introduced several features and enhancements. Let us delve into Java 14 new features.
1. Java 14 Switch Expressions – JEP 361
Initially introduced as a preview feature in JDK 12 and persisting as preview features in Java 13, switch expressions have now undergone standardization, becoming an integral component of the development kit. Consequently, developers can leverage this feature in production code rather than confining its use to experimentation in preview mode.
- When utilizing the arrow (
->
) operator, the yield keyword can be omitted. - When employing the colon (
:
) operator, the yield keyword is necessary. - For scenarios involving multiple statements, curly braces are used along with the yield keyword.
Consider a simple snippet.
var result = switch (day) { case "Monday", "Tuesday", "Wednesday","Thursday", "Friday" -> yield "Weekday"; case "Saturday", "Sunday" -> yield "Weekend"; default -> "Invalid day."; }; return result;
2. Java 14 Text Blocks (JEP 368)
Java 13 introduces a new feature called text blocks, which simplifies the creation of multi-line strings. Text blocks use triple double quotes ("""
) to define the start and end of the block. This eliminates the need for escape characters and makes it easier to write and read HTML or any other multi-line content directly within the source code. Building on the enhancements introduced in JDK 13 for more convenient use of multiline strings, text blocks in their second preview now incorporate two additional escape sequences:
\:
to signify the end of the line, preventing the introduction of a new line character.\s:
to denote a single space.
Here is a simple example demonstrating the usage of text blocks in Java 14.
public class TextBlockExample { public static void main(String[] args) { String multilineString = """ This is a multiline \ text block in Java 14. \ It allows for easy \ formatting without the need \ for escape characters. \ Using escape sequences like \: at the end of the line \ prevents introducing a new line character. \ Additionally, \s can be used to indicate a single space. """; System.out.println(multilineString); } }
3. Pattern matching for instanceOf operator
This represents a preview feature within the Java 14 Features. The instanceOf
keyword, also recognized as the type comparison operator, serves to compare the instance with a type. When assessing whether an object (instance) is a subtype of a given type, the instanceOf
operator is employed. Its outcome is either true or false, yielding true if the left side of the expression is an instance of the class name on the right side.
The instanceOf
operation yields a true result when an object belongs to a specified class or its superclass; otherwise, it triggers a compilation error. Consider the example of a Student who can take on the type of CommerceStudent or EngineeringStudent. Depending on the context, we can employ the instanceOf
operator here. The conventional instanceOf
condition invariably involves a typecasting statement in the subsequent line.
The novel feature obviates the need for a typecasting statement, allowing direct usage of the instance based on pattern matching.
// instanceof after Java 14 Pattern Matching feature if (student instanceof CommerceStudent cs) { System.out.println(cs.getStudentDetails()); }
4. Records – JEP 359 (Preview)
The Record
type has been introduced as a preview feature in Java 14 and is designed for use as plain immutable data classes facilitating data transfer between classes and applications.
Similar to Enum
, a record is a special class type in Java, intended for situations where a class is created solely to serve as a plain data carrier.
An essential distinction between a class and a record is that a record strives to eliminate all the boilerplate code necessary for setting and getting data from an instance. Records delegate this responsibility to the Java compiler, which automatically generates the constructor, field getters, hashCode()
, equals()
, and toString()
methods.
5. Helpful NullPointerExceptions
This addition is a recent inclusion in the Java 14 Features list. Identifying NullPointerExceptions can be challenging at times because the Java stack trace only provides the line number where the NPE occurs, without revealing the name of the object whose value is null. In such instances, we often need to manually deduce the object with the null value. With the introduction of this new feature, the compiler will now display the precise object name with a null value. However, to leverage this feature, a specific setting is required beforehand.
To enable this feature, the VM option -XX:+ShowCodeDetailsInExceptionMessages
must be set, as it is disabled by default. Once activated, the compiler will include the object names with null values in the exception messages, aiding in more effective debugging.
Consider the following Java code:
public class NullPointerExceptionExample { public static void main(String[] args) { Person person = null; try { // Accessing a method on a null object String name = person.getName(); System.out.println("Name: " + name); } catch (NullPointerException e) { System.err.println("NullPointerException caught!"); e.printStackTrace(); } } } class Person { private String name; public String getName() { return name; } }
In this example, we have a Person
class with a getName()
method. In the main
method, we create a Person
object and set it to null
. When we attempt to access the getName()
method on the null object, it will result in a NullPointerException
. If we set the VM option -XX:+ShowCodeDetailsInExceptionMessages
, the stack trace would include more information about the null object:
NullPointerException caught! java.lang.NullPointerException: Cannot invoke "Person.getName()" because the return value of "person.getName()" is null at NullPointerExceptionExample.main(NullPointerExceptionExample.java:7)
Now, it explicitly mentions that the issue is related to the method call person.getName()
, and it also indicates that the return value is null, providing more insight into the cause of the NullPointerException
.
6. Incubating Features
- Foreign Memory Access API (JEP 370): This introduces a new API enabling Java programs to safely and efficiently access foreign memory, such as native memory, outside the heap. Many Java libraries, including
mapDB
andmemcached
, access foreign memory, and the Foreign Memory Access API provides a cleaner solution compared to existing methods likeByteBuffer API
andsun.misc.Unsafe
API. The API is built upon three main abstractions:MemorySegment
,MemoryAddress
, andMemoryLayout
, offering a secure way to access both heap and non-heap memory. - Packaging Tool (JEP 343): Traditionally, application developers delivered Java code through JAR files for users to run within their JVMs. However, users increasingly expected installers for easy deployment on native platforms like Windows or macOS. JEP 343 addresses this need by allowing developers to use
jlink
to minimize the JDK to essential modules. The packaging tool then creates a lightweight image that can be installed as an executable on Windows or a disk image on macOS.
7. JVM Features
- ZGC on Windows (JEP 365) and macOS (JEP 364) – Experimental: The Z Garbage Collector, known for its scalability and low-latency characteristics, was initially introduced as an experimental feature in Java 11, exclusively supported on Linux/x64. Java 14 extends its support to Windows and macOS based on the positive feedback received for ZGC on Linux. Although it remains an experimental feature in Java 14, plans are in place for it to transition into a production-ready state in the upcoming JDK release.
- NUMA-Aware Memory Allocation for G1 (JEP 345): Unlike the Parallel collector, the G1 garbage collector lacked implementation for Non-Uniform Memory Access (NUMA). Recognizing the performance benefits of running a single JVM across multiple sockets, JEP 345 was introduced to make the G1 collector NUMA-aware. There are currently no intentions to replicate this feature across other HotSpot collectors.
- JFR Event Streaming (JEP 349): This enhancement enables continuous monitoring of JDK’s flight recorder data by exposing it for direct reading or streaming. The modification involves updates to the
jdk.jfr.consumer
package, empowering users to read or stream the recording data seamlessly.
8. Conclusion
In conclusion, Java 14 reflects a commitment to enhancing the language’s capabilities, addressing developer concerns, and improving performance. The introduction of features like records, pattern matching, and the Foreign Memory Access API simplifies code, making Java a more modern and developer-friendly language. As Java continues to evolve, these additions contribute to its adaptability in addressing contemporary programming challenges. Developers are encouraged to explore and adopt these features to benefit from improved productivity and performance in their Java projects.