Java’s internal systems and syntax are constantly evolving, and these changes happen primarily through the Java Community Process (JCP) and Java Enhancement Proposals (JEPs). Together, the JCP and JEPs define the path by which new features can be described, designed, and—hopefully—introduced into the JVM. They keep the Java language and platform dynamic and the community engaged. With JDK 24 so close to its planned release date, now is a good time to take a look at the upcoming JEPs making their way through the process.
Stages of the JEP process
You can check the JEP Index on the OpenJDK homepage for a catalog of all the JEPs, past and present, submitted for Java. The sheer size and scope of the index can be overwhelming at first. It’s not immediately clear what each JEP is about and which ones are more significant. You might expect major projects like virtual threads would be distinguished from proposals of smaller scope, but there is no such distinction. All the JEPs are listed, past and present, showing the complete history of Java’s evolution.
Instead of scope, the JEPs are organized according to their stage of development:
- In-flight JEPs are proposals being worked on right now for inclusion in a future version of Java. This includes everything from proposals that are in preview and available for experimentation to those that have recently been accepted for development. All the proposals in this set have already been vetted along the way and are likely to arrive in a future Java release.
- Submitted JEPs have come through the creation process and are now officially submitted but have not been accepted. Once they are accepted, they will move to the in-flight stage.
- Draft JEPs are proposals that are being worked on to get them into a state where they are ready for official submission. When that happens, they’ll move up to submitted JEP status.
- Delivered feature, infrastructure, and informational JEPs are all the successful JEPs of the past that have become part of the JVM. Some have even been delivered and then modified by further JEPs.
- Withdrawn JEPs are proposals that didn’t work out and were withdrawn.
You’ll also notice Process JEPs at the head of the index. These are procedural JEPs that help you understand and define the process itself.
Sometimes, larger JEPs are broken down into parts or stages. For example, JEP 462: Structured Concurrency (Second Preview) has an individual entry in the delivered features set.
The most notable in-flight JEPs right now
There are numerous interesting JEPs in the pipeline currently. The proposals I’ve highlighted are focused on tuning and refactoring the JVM and expanding and enhancing the language.
JEP 485: Stream Gatherers
As I discussed in my deep dive on the topic, stream gatherers make functional operations more customizable. The Stream Gatherer API exposes a low-level operator interface called a gatherer. Developers can use gatherers for operations on streams that were difficult or impossible before, like working with homogeneous collection types.
The deep dive was based on a preview of the feature. JEP 485 is the proposal to accept this feature as a finalized part of the platform. It’s the culmination of twp previous proposals: JEP 473 and JEP 461.
Stream Gatherers is not the kind of feature you need every day, but when you do need it, it’s awesome to have. It turns a frustrating edge case into a simple solution.
JEP 484: Class-File API
The Class-File API is targeted at library and framework developers who need to decorate the compiled output of Java programs with additional features. This is a long-standing approach in Java. The Java ecosystem has many tools for this type of development, but the faster pace of JDK changes makes having a more standardized approach important.
The Class-File API is a standard mechanism for parsing, manipulating, and outputting a framework or library’s .class
structures. Other tool developers (and the JDK itself) can then build on the provided output.
JEP 478: Key Derivation Function API (Preview)
JEP 478 is a move to improve and expand on Java’s native ability to deal with cryptographic material like keys and hashes. It’s intended to make these operations more robust, including forward-looking capabilities to help future-proof against quantum computing attacks.
Developers involved in cryptography would use the Key Derivation Function API for things like hashing passwords using advanced algorithms like Argon2. JEP 478 upgrades Java’s built-in cryptographic support and better positions it for the coming years.
JEP 478 is a preview proposal currently, meaning it likely has a way to go before it lands as an official feature.
JEP 472: Prepare to Restrict the Use of JNI
Part of Project Panama’s effort to replace the JNI with the Foreign Function Memory API, JEP 472 is an indication that the JVM is moving toward deprecating the Java Native Interface. This proposal is a heads-up for application developers that the time is coming when JNI will be restricted by default. This JEP is concerned with making the JNI and FFM API more consistent and safe. Developers using JNI or FFM will be affected by this change because it requires these features to be explicitly enabled and issues warnings if they are not.
JEP 468: Derived Record Creation (Preview)
Records are immutable objects, added not long ago to Java. JEP 468 introduces a simplified way to create clones of records with specific fields marked as mutated. Records are often copied as a way to modify them. This JEP takes a task that requires boilerplate and adds language-level support for it via the with
keyword.
The proposal’s authors provided an example of scaling an existing Point
instance (nextLoc
) by 2 in a new finalLoc
instance:
Point finalLoc = nextLoc with {
x *= 2;
y *= 2;
z *= 2;
};
A Point
class in this example refers to a three-dimension integer record. This eliminates any need to add chaining methods to the Point
class. Here’s an example of chaining:
Point finalLoc = nextLoc
with { x *= 2; }
with { y *= 2; }
with { z *= 2; };
Overall, the JEP makes a nice addition to the power of records.
JEP 198: Light-Weight JSON API
The feature proposed in JEP 198 is something I’ve wanted for over a decade. Dealing with JSON is a fact of life in modern programming, it crops up everywhere and there are good reasons for it. Using JSON in JavaScript is incredibly easy, whereas in Java it requires a third-party library. At times, these APIs are not easy to use.
Unfortunately, JEP 198 originated in 2014 and hasn’t been updated since 2017. However, there has been some activity on the OpenJDK mailing list. This is an example of a worthwhile JEP that is “in-flight” but also not moving quickly. Here’s hoping for more active development in the future.
JEP 479: Remove the Windows 32-bit x86 Port
JDK 21 deprecated 32-bit windows, and JEP 479 completes the job. Once this proposal becomes part of Java, the Java platform will no longer support 32-bit windows. The JEP describes how removing these code paths will streamline the JVM.
JEP 218: Generics over Primitive Types
Part of project Valhalla, JEP 218 is the ability to use primitive types in generics. This is a major improvement to the basic Java syntax and implies a significant amount of internal planning and refactoring. Unifying generics and primitives means we are getting away from primitive wrappers and (auto)boxing. This clears the way for a thoroughgoing unification of primitives and objects and the introduction of value types.
This will be the biggest change to the way we write Java in a long time. It is still being actively worked on but no hard date is set.
JEP 483: Ahead-of-Time Class Loading & Linking
JEP 483 is a great example of the JVM team at work on improving the underlying behavior of Java. The end result is a better platform; in this case, one that starts and reloads faster.
The general idea is that the JVM is adding the means to quickly load classes with other areas of dynamism preserved, resulting in faster startup and warmup times. Application developers won’t have to do anything special to take advantage of this feature; we get it for free in coming versions of the HotSpot JVM.
JEP 475: Late Barrier Expansion for G1
Like JEP 483, JEP 475 is a refactoring that won’t be directly used by application developers. Instead, it improves the performance and accessibility of the HotSpot JVM for platform developers implementing garbage collection routines.
JEP 475 is especially focused on reducing memory and time in the garbage collector, which is critical for making Java a stronger platform for the cloud. These kinds of improvements—technologically demanding operations that happen behind the scenes—are important for keeping the Java platform relevant.
JEP 450: Compact Object Headers (Experimental)
Another internal performance improvement, JEP 450 is designed to reduce the in-memory size of Java objects. Real-world testing has shown that much of the heap space occupied by objects is object header data. That means that, as the JEP says, “Cutting down the header of each object from 96 to 64 bits means improving overall heap usage by more than 10 percent, since the header is a fixed cost for every object. A smaller average object size leads to improvement in memory usage, GC pressure, and data locality.”
This is another welcome internal refactor that we can look forward to silently improving the way our programs run.
JEP 111: Additional Unicode Constructs for Regular Expressions
JEP 111 looks to expand the character types that regular expressions can handle, covering more of the Unicode tech standard. Specifically, it is adding the following types of chars that can be handled in strings:
- Unicode Name Properties:
N {...}
- Extended Grapheme Clusters:
X
- Fix the broken canonical equivalent support
- Unicode line-break sequence, as suggested at TR#18 Line Boundaries:
R
- Perl style construct for named capturing group and capturing group:
g {...}
- More complete Unicode properties, as in
p {IsXXXX}
- Horizontal/vertical whitespace:
h H v V
Conclusion
Although I’ve covered many of the in-flight JEPs, there are several others, not to mention the wealth of draft-stage proposals. Looking at the index is a great way to get a sense of the immense amount of work going into Java. In this article, I focused on proposals for tuning and refactoring the JVM and expanding and enhancing the language.