Top JDK 25 Features You Need to Know
Java 25 shipped September 16, 2025 as the latest Long-Term Support (LTS) release. Sixteen JEPs landed, balancing developer ergonomics with runtime performance. Here’s the breakdown.
Language Improvements
Compact Source Files (JEP 512)
Finalized in Java 25. Single-file scripts now simpler:
import java.util.*;
void main() {
List<String> names = ["Alice", "Bob", "Charlie"];
names.forEach(System.out::println);
}
No class wrapper needed. Works with instance main methods too.
Module Import Declarations (JEP 511) - Preview
Import entire module at once:
import module java.base;
import module java.sql.*;
void main() {
// Collections, streams, I/O all available
var map = new HashMap<String, Integer>();
}
Pairs with compact source files for teaching and quick scripts.
Flexible Constructor Bodies (JEP 513)
Statements before super() or this() calls:
public class BankAccount {
private final String id;
public BankAccount(String type) {
// Initialize fields before super() call
this.id = UUID.randomUUID().toString();
if (type == null) {
throw new IllegalArgumentException();
}
super(type);
}
}
Useful for validation and field initialization.
Primitive Types in Patterns (JEP 507) - Third Preview
Pattern matching now works with primitives:
if (obj instanceof int i) {
System.out.println("Integer: " + i);
}
switch (value) {
case int i when i > 0 -> "positive";
case int i -> "non-positive";
}
API Additions
Scoped Values (JEP 506) - Final
Modern replacement for ThreadLocal. Immutably share data with child threads:
static final ScopedValue<String> USER = ScopedValue.newInstance();
public void handleRequest(Request req) {
ScopedValue.runWhere(USER, req.user(), () -> {
// Available in this thread and child threads
processOrder();
});
}
No ThreadLocal cleanup issues. Value flows to virtual threads automatically.
Structured Concurrency (JEP 505) - Fifth Preview
Treat concurrent tasks as a single unit:
try (var scope = StructuredTaskScope.open()) {
var user = scope.fork(() -> fetchUser(id));
var prod = scope.fork(() -> fetchProducts());
var order = scope.fork(() -> fetchOrder(id));
scope.join();
// All complete or all failed
render(user.result(), prod.result(), order.result());
}
Error handling and cancellation simplify dramatically.
Key Derivation Function API (JEP 510) - Final
Standard KDF in java.security:
Key key = KDF.deriveKey("HKDF-SHA256",
SecretKey secret,
"app-key".getBytes(),
256);
No need for BouncyCastle for basic KDF operations.
Vector API (JEP 508) - Tenth Incubator
Express vector computations that compile to SIMD:
var vector = FloatVector.fromArray(Float64.SPECIES, values, 0);
var result = vector.mul(vector).add(vector);
result.intoArray(output, 0);
Performance
Compact Object Headers (JEP 519)
Object headers reduced from 96-128 bits to 64 bits. Heap size shrinks 10-20% typical. No code changes needed.
Generational Shenandoah (JEP 521)
Shenandoah now supports generations:
-XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
Lower pause times with generational hypothesis.
JFR CPU-Time Profiling (JEP 509) - Experimental
Accurate CPU-time profiling:
java -XX:StartFlightRecording:cpu-time-profiling=enabled ...
Identify which method dominates latency in request paths.
What’s Stable Now
| Feature | JEP | Status |
|---|---|---|
| Compact Source Files | 512 | Final |
| Scoped Values | 506 | Final |
| Flexible Constructor Bodies | 513 | Final |
| Compact Object Headers | 519 | Final |
| Generational Shenandoah | 521 | Final |
| Key Derivation Function API | 510 | Final |
Upgrade Path
From Java 21 (previous LTS):
- Compile with
--release 25for new syntax - Enable preview features (
--enable-preview) for module imports, primitive patterns, structured concurrency - Test with JFR CPU profiling for latency analysis
Preview features need careful handling - may change between releases.
Bottom Line
Java 25 delivers practical value: cleaner syntax for scripts, safer concurrency with Scoped Values, memory savings via compact headers. Upgrade worthwhile for LTS support through 2033.