Java 24's Top Features Explained in 5 Minutes
With the release of Java 24, several new Java Enhancement Proposals (JEPs) have been introduced, bringing significant updates to the language. This article provides a concise overview of the most interesting and relevant features from this new version.
JEP 483: Faster Startup with Ahead-of-Time Class Loading
To improve application startup time, this feature makes application classes instantly available by monitoring the app during an initial run. It stores the loaded and linked files of all classes in a cache, which is then used in subsequent runs. According to tests described in the JEP, this can lead to startup time improvements of up to 42%, with the trade-off being the additional storage required for the cache.
JEP 466: A Standardized Class File API
First introduced as a preview in JDK 22, the Class File API is now a full feature. It provides a standard, official API for parsing, generating, and transforming Java class files. Since the class file format can change with every six-month Java release, this is a crucial update. Many libraries and frameworks that interact with compiled class files currently rely on third-party tools. With this standardized API, these tools can seamlessly support new JDK releases without manual updates.
JEP 485: Custom Intermediate Operations with Stream Gatherers
Previously a preview feature, Stream Gatherers are now finalized. They empower developers to create custom intermediate operations for streams. A helpful way to understand this is to see the gatherer
method as the equivalent for intermediate operations to what the collect
method is for terminal operations.
For instance, imagine you have a stream of strings and want to select distinct elements based on their length rather than their content. The standard distinct()
method doesn't support this. With Stream Gatherers, you can implement a custom distinctBy
operation to achieve this.
Note: Here is a practical code example of how this could work.
// Example: Using a custom gatherer to find distinct strings by length
Stream<String> stream = Stream.of("one", "two", "four", "five"); // lengths 3, 3, 4, 4
// A hypothetical 'distinctBy' intermediate operation, powered by a custom Gatherer,
// would keep the first element encountered for each unique string length.
List<String> result = stream.gather(Gatherers.distinctBy(String::length)).toList();
// The result will contain one string of length 3 and one of length 4.
System.out.println(result); // Expected Output: [one, four]
JEP 472: Enhanced Security by Restricting JNI
The Java Native Interface (JNI) allows Java code to interoperate with native code, but this capability comes with inherent security risks. To mitigate this, users of JNI will now receive warnings. In a future release, developers will be required to explicitly enable the use of JNI, adding a layer of intentional security.
JEP 479 & 501: Phasing Out 32-Bit Support
Java is officially ending its support for 32-bit platforms. With Windows 10—the last Windows version with 32-bit support—reaching its end-of-life, Java will no longer support it. Additionally, the 32-bit port for Linux operating systems is now deprecated and slated for removal in a future release.
JEP 486: Disabling the Security Manager
The Security Manager, which has been deprecated since JDK 17, is now disabled in this release. It was rarely used and costly to maintain, and its removal is planned for a future version.
JEP 490: Simplifying ZGC by Removing Non-Generational Mode
The non-generational mode of the Z Garbage Collector (ZGC) has been removed. The generational ZGC is now considered a superior solution for the majority of use cases, simplifying the collector's configuration and maintenance.
JEP 491: Boosting Virtual Thread Performance
This feature improves the scalability of Java code that relies on synchronized methods and statements. It allows virtual threads that are blocked in such constructs to release their underlying platform threads, making them available for other virtual threads to use. This leads to better performance and resource utilization when working with virtual threads.
JEP 493: Smaller JDK Runtimes
It is now possible to reduce the size of the JDK by approximately 25%. This is achieved by enabling the JLink
tool to create custom runtime images without using the JDK's JMOD files, making deployments lighter and more efficient.
JEP 496 & 497: Preparing for the Quantum Era
To enhance security against future quantum computing attacks, Java 24 introduces two quantum-resistant cryptographic implementations.
- JEP 496 (ML-KEM): Provides an implementation of the Module-Lattice-based Key Encapsulation Mechanism (ML-KEM). This is used to secure symmetric keys exchanged over insecure channels using public key cryptography.
- JEP 497 (ML-DSA): Implements the Module-Lattice-based Digital Signature Algorithm (ML-DSA). Digital signatures are used to verify the authenticity of data and protect it from unauthorized modifications.
JEP 498: Warnings for Unsafe Memory Access
Finally, a runtime warning will now be issued the first time any memory access method in sun.misc.Unsafe
is invoked. All of these unsupported methods were already deprecated in JDK 23 and have been replaced by standard, safer APIs.