
Java programmer expert
With the release of the next version of the Java JDK fast approaching, we decided to take a closer look at the Java new features on our blog. The target release date is 19 September 2023. However, it is already possible to download this version in Early Access and start experimenting. (In a previous article we discussed the features of the Java 20 JDK.)
Java 21 (after Java 17) is again a long-term support (LTS) release, which means that Oracle will provide free updates for at least five years, until September 2028, and extended paid support until September 2031.
Let’s take a quick look at what’s in JDK 21 and what we can expect. We’ll start with the most exciting new features and improvements.
Virtual threads are lightweight threads that make it much easier to write, maintain and monitor high-performance, concurrent applications. This includes the ability to scale server applications written in thread-on-demand by making efficient use of hardware, the ability to easily migrate existing code that uses the lang.Thread API to virtual threads with minimal changes, and the ability to easily debug and profile virtual threads using existing JDK tools.
Virtual threads were introduced in JDK 20 and JDK 19 and will be completed in JDK 21. With JDK 21, virtual threads now support local thread variables throughout runtime and are not allowed to create virtual threads without these variables. The guaranteed support for local thread variables ensures that many existing libraries can be used with virtual threads without modification.
Another interesting new feature is sequential collections, and JDK 21 introduces the design of sequential collections and introduces interfaces for sequential collections. Each collection has a well-defined first, second, and so on, down to the last element. Uniform APIs are provided for retrieving first and last elements and for processing elements in reverse order. The motivation for this proposal is the fact that the Java collection framework does not have a collection type that represents a sequence of elements with a defined order. It also lacks a consistent set of operations that apply to these collections. These gaps have been a problem and a source of complaint. The proposal is to define interfaces for sequences of collections, sets, and maps, and to add them to the existing hierarchy of collection types. All of these new methods have predefined implementations.
Record patterns enable the deconstruction of record values. Record patterns and type patterns can be nested, enabling powerful, declarative, and composable data retrieval and processing. Design goals include extending pattern matching to destruct instances of record classes and adding nested patterns to enable data query composition. This feature has been developed in parallel with pattern matching for switch expressions.
This feature allows a switch expression/command to test itself against multiple patterns, each with a specific action, allowing complex data queries to be expressed safely and concisely. This feature was originally proposed in JDK 17, modified in subsequent versions, and was to be completed and modified in JDK 21 based on feedback and experience from Java developers. The main changes from previous versions of JEP include removing parentheses in patterns and allowing qualified enumeration constants, then increasing the safety of expressions and switch statements by requiring that all possible input values are covered. Another goal is to ensure that existing switch statements remain functional without modification and are executed with the same semantics.
This is a feature, in the form of an example in JDK 21, that complements the existing string literals and text blocks in Java by combining such text with embedded expressions and processors to produce specialized results. This language feature and API is intended to simplify the writing of Java programs by making it easy to express strings that contain values that are computed at runtime. It promises to improve the readability of expressions, increase program security, preserve flexibility, and simplify the use of APIs that accept strings written in languages other than Java. It also allows the development of non-string expressions created by combining text literals and embedded expressions.
This feature improves code readability and maintenance by allowing patterns to be created without specifying a component name or type. Unnamed variables can be initialized but are not used. The goal is to eliminate unnecessary nested patterns and identify unused variables.
This feature is focused on simplifying the writing of first Java programs, where students may not immediately understand language features designed for more complex projects. It allows you to create simple programs and gradually extend them with more advanced functionality.
Structured concurrency simplifies programming in a concurrent environment by using an API that manages groups of related tasks as units of work. This improves error management, which increases reliability and observability. This feature, previously tested in JDK 20 and JDK 19, is now supported as a sample API in the util.concurrent package.
The preview version of this feature allows immutable data to be shared between threads and components. Scoped values are preferred over thread-local variables, especially when using a large number of virtual threads. This feature improves code readability and robustness.
Disable dynamic agent loading – this change aims to improve the integrity of the JVM by warning when agents are dynamically loaded while the application is running. The aim is to improve the balance between service changes and code integrity, and to ensure that most tools are not affected by this change.
This feature enables the use of algorithms to secure symmetric keys using public cryptography. The goal is to enable applications to use algorithms such as the RSA Key Encapsulation Mechanism (RSA-KEM) and the Elliptic Curve Integrated Encryption Scheme (ECIES) in a variety of protocols and cryptographic schemes.
This feature aims to improve application performance by using separate generations for young and old objects. Generational ZGC enables more efficient collection of young objects, resulting in lower memory consumption and lower garbage collection load (collection of unused allocated memory).
This enables Java programs to interoperate with code and data outside the Java runtime. It allows calls to external libraries and secure memory access, replacing JNI (Java Native Interface).
This API allows calculations to be performed vectorially, resulting in better performance than scalar calculations. The goal is to provide a simple and reliable solution for vector computation on supported architectures.
This change is intended to remove the 32-bit port for Windows x86 in a future release. Windows 10, the last Microsoft operating system to support 32-bit mode, will end its lifecycle in October 2025.
In addition to these features, JDK 21 is also in the process of changing the naming of network interfaces in Windows. An experimental “compact object headers” feature is also planned to reduce the size of object headers in the JVM, thereby reducing memory footprint.
If you are interested in the new features of Java JDK 21 and would like to learn more about them, visit the official OpenJDK website.