Hello everyone,
Six months have passed since the last article about Java 24 and Java 25 - and Java continues to tick along at the usual six-month interval. Java 26 was released on March 17, 2026, the first release after the LTS milestone Java 25. No long-term support this time, but again a package of finished features and previews that show where the platform is developing.
Java 26 comes with ten JEPs: five of them are final, four are in the next preview round, and one is in the incubator. This time it’s less about spectacular new syntax and more about fundamental work: HTTP/3, a faster JVM start thanks to Ahead-of-Time Object Caching, more throughput in the G1 Garbage Collector - and a change that is quieter but can have consequences for existing code.
Let’s look at what really matters.
The finalized features
HTTP/3 for the HTTP Client (JEP 517)
The HTTP client from the java.net.http package now also supports HTTP/3, which is based on the QUIC protocol. QUIC brings stream-level flow control, lower latency when establishing a connection, and the ability to switch network paths without losing the connection - useful when your client jumps between Wi-Fi and cellular.
The transition is intentionally not an autopilot. You explicitly request HTTP/3, otherwise HTTP/2 remains the default:
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://julianpaul.dev/"))
.version(HttpClient.Version.HTTP_3)
.build();
If the server does not support HTTP/3, the client transparently falls back to HTTP/2. For you, hardly anything changes in the application code - the migration is a one-line change, not a rewrite.
Faster startup thanks to AOT Object Caching for each GC (JEP 516)
With Java 26, Project Leyden provides another component for faster start times. The AOT cache (Ahead-of-Time) has so far not been able to work with every garbage collector - especially ZGC, the collector for low latencies, was left out because the cached objects were stored directly in the GC-specific format.
JEP 516 solves this by loading objects sequentially in a GC-neutral format, rather than mapping them 1:1 into a specific GC layout. The result: The AOT cache now works with any garbage collector without sacrificing startup performance. For cloud-native applications with a short lifespan – classic microservices, Lambda-like workloads – this is a tangible win.
G1 GC: More throughput through less synchronization (JEP 522)
The G1 Garbage Collector has always balanced latency and throughput. The price for this: Application threads have to coordinate with GC threads, which creates synchronization effort. JEP 522 reduces this effort and shrinks the code that the JVM inserts for write barrier checks - without touching the basic architecture of G1.
This isn’t a feature you see in the code. It’s one of those cases where a minor release just speeds up without you having to do anything.
Cleanup: The Applet API is history (JEP 504)
Since Java 17 was marked as “deprecated for removal”, the Applet API has been permanently removed with Java 26. No current browser supports applets anymore, and no current JDK has been able to meaningfully run them in recent years. If your code still imports java.applet.* somewhere - that’s the time to finally dispose of it.
The Silent Revolution: Warnings for final fields (JEP 500)
The most inconspicuous JEP in this release is also the one with the greatest potential to disrupt existing code bases. Previously, Reflection could easily overwrite a final field - so final was never really final, but rather a recommendation that could be overridden with setAccessible(true). Many frameworks (serialization, dependency injection, test mocking) make use of exactly this.
Java 26 is starting to put an end to that. If your code mutates a final field via reflection, you will immediately receive a warning:
WARNING: Final field value in class dev.julianpaul.example.Box
has been mutated reflectively
WARNING: Mutating final fields will be blocked in a future release
Your code still runs - JEP 500 is pure preparation, not a break. You control the behavior via a VM flag:
# Standard in Java 26: nur warnen
--illegal-final-field-mutation=warn
# Zukünftiges Verhalten schon jetzt testen: blockieren
--illegal-final-field-mutation=deny
Pro tip: If you use frameworks like Jackson, Gson, Mockito or older DI containers, it’s worth doing a test run with
--illegal-final-field-mutation=denyin a CI pipeline. This allows you to see early on which dependencies could break in a future Java version - long before it becomes a problem in production.
This is the first visible step towards “final means final”. For you this means: If you use final fields as an expansion point (consciously or out of habit), now is the time to reconsider.
Which already shines through as a preview
In addition to the final features, Java 26 shows what is being worked on in the background. Three previews are particularly interesting because they show where the next LTS versions are headed.
Lazy Constants (JEP 526, 2. Preview)
Previously the choice for fields was binary: either final and initialized when the object was created, or mutable and without the performance guarantees of final. Lazy Constants close the gap - a value is only calculated the first time it is used, but is then considered a real constant by the JVM:
private final LazyConstant<Settings> settings =
LazyConstant.of(this::loadSettingsFromDatabase);
public Locale getLocale() {
return settings.get().getLocale();
}
There are also variants for collections that only calculate each element when needed:
private final List<Double> squareRoots = List.ofLazy(100, Math::sqrt);
This is particularly interesting for expensive initializations - configuration data, resources that are only needed with the first request - without you having to write your own double-checked locking construct.
Structured Concurrency (JEP 525, 6. Preview)
Structured Concurrency has been with us as a preview for several Java versions and continues to mature. The idea remains: Related tasks on different threads are treated as a single unit, with clean error handling and cancellation instead of manually managed thread corpses. The 6th preview primarily brings refinements to the API - a sign that finalization is getting closer.
Primitive Types in Patterns (JEP 530, 4. Preview)
Pattern matching has so far only recognized primitive types to a limited extent. JEP 530 now allows pattern matching directly on byte, short, int, double & Co. - also in switch:
double value = ...;
switch (value) {
case byte b -> IO.println(value + " passt in byte: " + b);
case short s -> IO.println(value + " passt in short: " + s);
case int i -> IO.println(value + " passt in int: " + i);
case double d -> IO.println(value + " bleibt double: " + d);
}
This makes pattern matching consistent for all types - whether reference or primitive - and is another building block on the way to truly consistent, expressive pattern matching in Java.
Pro Tips/Warnings
Do not use productively without a plan: Java 26 is non-LTS. For production systems, Java 25 (LTS) remains the more solid choice until at least 2027. Java 26 is worth it if you want to see early on where the platform is headed or want to specifically try out features like HTTP/3 or AOT Object Caching with ZGC.
Test JEP 500 now: Don’t wait until
--illegal-final-field-mutation=denybecomes the standard. If you have reflection-heavy libraries in the stack, test now against Java 26 with deny mode enabled - better a warning today than a breaking change in two years.
Conclusion: Continuity instead of big leaps
Java 26 is not a release with loud headlines - but one with solid foundational work. HTTP/3, a GC-independent AOT cache and a higher-throughput G1 are tangible improvements that work in the background. The actually relevant development is JEP 500: The first visible step to make final truly final potentially affects every code base that relies on reflection-based frameworks.
The previews – Lazy Constants, Structured Concurrency, Primitive Types in Patterns – show that the major construction sites from the last releases will be consistently continued. With Java 27 in September 2026, the six-month rhythm continues seamlessly. Until then, it’s worth taking a look at Java 26, especially if you’re using HTTP/3 or ZGC.
![[EN] Java 26: What's new?](/images/Java26-BlogHeader.jpeg)