Java 21, the next planned version of standard Java, will become generally available on September 19, 2023. It’s been in Rampdown Phase Two since July 20, 2023, and it’s now feature-complete, which means no more JEPs will target this release.
The 15 JEPs in Java 21 cover a range of functionality, including string templates and structured concurrency previews, virtual threads, and a key encapsulation mechanism API. Here are a few of the highlights.
If you are reading this article before the official launch, you can use a Java 21 early-access build and the jshell
tool to try the JEPs described in this article by downloading Java 21, firing up your terminal, checking your version, and running jshell
, as shown below. Note that you might see a newer version of Java depending on what you downloaded.
[mtaman]:~ java -version
openJava version "21-ea" 2023-09-19
OpenJava Runtime Environment (build 21-ea+34-2490)
OpenJava 64-Bit Server VM (build 21-ea+34-2490, mixed mode, sharing)
[mtaman]:~ jshell --enable-preview
| Welcome to JShell -- Version 21-ea
| For an introduction type: /help intro
jshell>
There are 15 JEPs in Java 21: four are final (which means you can use them in production code), six are previews, and one is an incubator module. There are also four other JEPs that are important but don’t represent new features, as you’ll see shortly.
The preview features are fully specified and implemented, but they might change in the future; therefore, they should not be used for production code. Use the --enable-preview
JVM flag to try those features.
The incubator module is published to solicit developer feedback. Such a module’s API could be altered or disappear entirely (that is, not be released in future Java releases). To use the incubator module, add the --add-modules
JVM flag, and be sure to send feedback to the JEP 448 team.
The following are the final JEPs:
These are the preview JEPs.
JEP 448, Vector API (sixth incubator), is the only incubator JEP.
The following are the other JEPs:
Sequenced collections, JEP 431. The proposal for sequenced collections introduces interfaces that represent collections with a specific encounter order. Each collection contains elements from the first to the last, and uniform APIs enable operations with the first and last elements as well as reverse order processing.
The motivation behind this proposal stems from the need for a collection type in Java’s collections framework that adequately represents a sequence of elements with a well-defined encounter order. Additionally, there needs to be a consistent set of operations that can be applied to collections.
This JEP addresses these gaps by defining interfaces for sequencing collections, sets, and maps, which will be incorporated into the existing collections type hierarchy. All the newly introduced methods come with default implementations.
Record patterns, JEP 440. Record patterns, previewed in both Java 19 and Java 20, break down record values. Record and type patterns can be nested to enable a potent, expressive, and modular data navigation and processing form.
This JEP’s goals include expanding pattern matching to break down instances of record classes and adding nested patterns, enabling more versatile data queries. This feature has been developed alongside pattern matching for switch expressions and statements (JEP 441, which is described next).
The record patterns proposal in JEP 440 will finalize the feature with further refinements based on feedback. Besides minor editorial changes, the main alteration since the second preview was to remove support for record patterns appearing in the header of an enhanced for
statement, but that may be reproposed in a future JEP.
Pattern matching for switch, JEP 441. Pattern matching for switch allows a switch expression or statement, each with a specific action, to be tested against various patterns, thus facilitating the safe and concise expression of complex data-oriented queries.
This feature was initially proposed in Java 17 and subsequently refined in Java 18 through Java 20. It will be finalized in Java 21 with further refinements based on feedback. Significant changes from previous JEPs include removing parenthesized patterns and permitting qualified enum constants, such as case constants, with switch expressions and switch statements.
The goals include enhancing the expressiveness and applicability of switch expressions and switch statements by allowing patterns in case labels, relaxing the historical null-hostility of a switch when that’s needed, and increasing the safety of switch statements by ensuring pattern switch statements cover all potential input values.
Another objective is to ensure that existing switch expressions and switch statements continue to compile and execute with identical semantics.
Virtual threads, JEP 444. This is the big one! The virtual threads JEP is one of the most significant updates in Java’s history. It represents lightweight threads that offer the potential to significantly simplify the process of developing, maintaining, and monitoring concurrent applications that demand high throughput.
The objectives of this JEP encompass facilitating the scalability of server applications following the thread-per-request pattern, ensuring optimal hardware utilization.
It also involves allowing existing code to employ the lang.Thread
API to seamlessly transition to virtual threads with minimal code modifications and facilitate the effortless debugging and profiling of virtual threads using current Java tools. Virtual threads were previously introduced in preview JEPs in both Java 19 and Java 20, and they will reach their finalized state in Java 21.
In Java 21, virtual threads offer constant support for thread-local variables, thus disallowing the creation of virtual threads without these variables. This guaranteed backing for thread-local variables expands the scope for using virtual threads without altering existing libraries and streamlines the transition of task-oriented code to incorporate virtual threads.
String templates (preview), JEP 430. String templates, a preview feature that’s new for Java 21, complement Java’s current string literals and text blocks by combining literal text with embedded expressions and processors to generate customized outcomes. This language feature and its API should simplify Java programming by enabling the straightforward expression of strings that incorporate runtime-computed values.
String templates aim for improved readability of expressions, enhanced program security, increased flexibility, and easier usage of APIs that accept strings written in non-Java languages.
The ability to develop nonstring expressions through the combination of literal text and embedded expressions is also a key objective.
Foreign function and memory API (third preview), JEP 442. The foreign function and memory API, a concept developed in Project Panama, has been worked on since Java 14—at that time, in two separate JEPs: Foreign Memory Access API and Foreign Linker API. The unified foreign function and memory API was previously previewed in Java 19 and Java 20. Its goal is to replace the cumbersome, error-prone, and slow Java Native Interface (JNI).
A third preview of the API empowers Java programs to interact with code and data beyond the Java runtime. This API efficiently invokes foreign functions and safely accesses foreign memory, allowing Java programs to call native libraries and process native data without the brittleness and risks associated with JNI.
The Java 21 preview brings refinements, including improved layout paths with a new element for dereferencing address layouts, centralized management of native segments’ lifetimes in the Arena interface, a fallback native linker implementation, and the removal of VaList
.
The JEP’s objectives encompass ease of use, performance, generality, and safety—and to that end, note that this JEP’s functionality should not be used to reimplement JNI on top of the foreign function and memory API or to alter JNI in any manner.
Unnamed patterns and variables (preview), JEP 443. This first preview of unnamed patterns and variables refers to two separate but related items. Nameless patterns correspond to a component of a record without the explicit mention of its name or type, whereas nameless variables can be assigned a value but remain unused. An underscore character, _
, represents both.
This JEP aims to enhance the readability of record patterns by omitting redundant nested patterns and to enhance the maintainability of code by identifying variables that need to be declared but won’t be used.
Unnamed classes and instance main methods (preview), JEP 445. This first preview of unnamed classes and instance main methods advances the Java language by making it possible for students to write their initial Java programs without the need to comprehend all the language features that are needed for complex projects.
The changes proposed in this JEP—which has a long name for a simple concept—mean that instead of employing a separate Java dialect, students can create concise declarations for single-class programs and gradually incorporate more-advanced features as their proficiency develops.
Consider when newcomers create an initial Java program such as the following:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
Veteran Java programmers will readily identify the constituents of this code upon initial inspection. However, newcomers might feel inundated by visibility modifiers, intricate concepts such as classes and static methods, superfluous method parameters, and a reference to System.out
. Wouldn’t it be appealing if a significant portion of these aspects could be eradicated, as follows:
void main() {
System.out.println("Hello world!");
}
This code will work as of Java 21 (if you enable the preview features). This functionality will provide a seamless entry point to Java while reducing the formalities associated with writing straightforward Java programs, such as scripts and command-line utilities.
Scoped values (preview), JEP 446. Scoped values, in this first preview phase, facilitate the exchange of unchangeable data within and across threads. They are the preferred option for local variables when you are dealing with many virtual threads because thread-local variables possess inherent flaws, such as unrestricted mutability, an indefinite lifespan, and costly inheritance.
By employing scoped values, data can be securely shared among different parts of an extensive program, eliminating the need for method arguments. This concept was developed during the incubation of Java 20, with the primary objectives being user friendliness, comprehensibility, resilience, and efficiency.
Structured concurrency (preview), JEP 453. Structured concurrency was incubated in Java 19 and Java 20. Structured concurrency as previewed in JEP 453 for Java 21 simplifies the parallel execution of tasks by introducing a structured concurrency API. This approach treats batches of interrelated tasks, executed in separate threads, as a cohesive unit of work.
Structured concurrency enhances error handling and cancellation procedures, ultimately improving reliability and facilitating better monitoring.
As a preview API, structured concurrency will be included in the java.util.concurrent package. The main alteration this time is that the StructuredTaskScope::Fork() method now returns a Subtask instead of a Future.
The objectives of structured concurrency encompass promoting a style of concurrent programming that minimizes common risks associated with cancellation and shutdown, such as thread leaks and delays in cancellation, while enhancing concurrent code’s traceability.
Vector API (sixth incubator), JEP 448. The only incubator module in Java 21 should be familiar to many developers: The Vector API is now in its sixth incubation phase. It facilitates expressing vector computations that efficiently compile into optimal vector instructions on supported CPU architectures, resulting in superior performance compared to equivalent scalar computations. It was previously incubated in Java 16 through Java 20.
This latest version has performance enhancements and bug fixes. JEP 448 aims to achieve clarity, conciseness, platform independence, and dependable runtime compilation and performance on x64 and AArch64 architectures. Additionally, it strives for graceful degradation when a vector computation cannot be fully expressed as a sequence of vector instructions.
Generational ZGC, JEP 439. The Generational ZGC JEP aims to enhance application performance by expanding the Z Garbage Collector (ZGC) and its capabilities to manage distinct generations of young and old objects. Young objects often have a short lifespan, and introducing separate generations should enable ZGC to perform more-frequent collection of young objects.
Applications that use Generational ZGC (which first appeared in Java 11 as an experimental feature) are expected to gain several advantages.
These advantages should be attainable without a notable decrease in throughput compared to the nongenerational variant of ZGC.
Deprecate the Windows 32-bit x86 port for removal, JEP 449. The Windows 32-bit x86 port is slated for deprecation and eventual removal. This JEP aims to enhance the build system, causing it to generate an error message when it configures a build for Microsoft Windows 32-bit x86.
You will be able to suppress the error message through a novel configuration option. Furthermore, the strategy involves labeling the port and its associated port-specific functionality as deprecated in pertinent documentation, signaling their impending removal. So, now you know what to expect.
The proposal notes that Microsoft Windows 10, the final Windows version that supports 32-bit operation, is set to end its lifecycle in October 2025.
Prepare to disallow the dynamic loading of agents, JEP 451. This JEP proposes the issuance of alerts when agents are dynamically loaded into an operational JVM. These alerts prepare for a forthcoming update that will, by default, disallow the dynamic loading of agents, all in an effort to enhance inherent integrity.
Other objectives of the JEP encompass reevaluating the trade-off between serviceability, which involves impromptu modifications to executing code, and integrity, which assumes that running code remains unaltered without justification.
Additionally, the JEP seeks to ensure that most tools, which do not require the dynamic loading of agents, remain unaffected. The plan also entails aligning the capability to dynamically load agents with other superpower functionality, such as deep reflection.
This JEP involves mandating the approval of the application owner for the dynamic loading of agents, just as such approval has been obligatory for agents loaded during startup. This transformation will bring the Java platform closer to a default state of integrity.
Key encapsulation mechanism API, JEP 452. This new API facilitates the functioning of key encapsulation mechanism (KEM) algorithms, which are cryptographic methods used to safeguard symmetric keys through public cryptography.
With this JEP, your programs will be able to use KEM algorithms such as RSA Key Encapsulation Mechanism (RSA-KEM), the Elliptic Curve Integrated Encryption Scheme (ECIES), and algorithms being considered for the National Institute of Standards and Technology (NIST) Post-Quantum Cryptography standardization initiative.
Another aim is to enable the integration of KEMs within higher-level protocols such as Transport Layer Security (TLS) and cryptographic schemes, including Hybrid Public Key Encryption (HPKE). Security providers will be able to implement KEM algorithms using either Java or native code and include an implementation of the Diffie-Hellman KEM (DHKEM) as defined in RFC 9180.
Overall, Java 21 will be a remarkable release that brings many valuable and vital improvements to the language, with the most eagerly anticipated likely being the first nonpreview release of virtual threads. All the features and enhancements will provide developers with even more powerful tools to create high-quality applications. Whether you are a seasoned Java developer or just starting, this release is an excellent choice for your next project.
Mohamed Taman (@_tamanm) is CEO of SiriusXI Innovations and a Chief Solutions Architect for Nortal. He is a Java Champion, an Oracle ACE, a Jakarta EE ambassador, a JCP member, and a member of the Adopt-a-Spec program for Jakarta EE and Adopt-a-JSR for OpenJDK. Taman is Egyptian and based in Belgrade, Serbia.
Next Post