What's New in Java 25: The Complete Guide
18 JEPs, LTS release, and Java turns 30. Everything you need to know.
Overview
Java 25 (JDK 25) reached General Availability on September 16, 2025, and it’s a big one. It’s the new Long-Term Support (LTS) release — the first since JDK 21 in September 2023 — with at least 8 years of commercial support from Oracle.
Java Turns 30
Java celebrated its 30th anniversary in 2025. From applets to microservices, from J2EE to virtual threads — three decades of evolution, and Java 25 proves the language isn’t slowing down.
JDK 25 delivers 18 JEPs across these categories:
- 7 Finalized features (production-ready)
- 4 Preview features (opt-in with
--enable-preview) - 1 Incubator (Vector API, 10th round)
- 1 Experimental (JFR CPU-Time Profiling)
- 3 JFR enhancements
- 2 Removals
Language Features
Compact Source Files & Instance Main Methods (JEP 512) — Final
After previewing across JDK 21–24, the simplified entry point is now official. No more public static void main(String[] args) for simple programs.
Before (Java 8–24)
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
After (Java 25)
void main() {
println("Hello, World!");
}
Three lines. No class declaration, no static, no String[] args, no System.out. Perfect for scripting, teaching, and quick prototypes.
Module Import Declarations (JEP 511) — Final
Import all exported packages from a module in one line:
Module Imports
// Before: multiple import statements
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
// After: one module import covers everything
import module java.base;
You don’t need to modularize your own code to use this. import module java.base gives you access to java.util, java.io, java.time, and all other java.base packages in one shot.
Flexible Constructor Bodies (JEP 513) — Final
You can now execute statements before calling super() or this() in constructors. A long-awaited change.
Validate Before super()
public class Employee extends Person {
public Employee(String name, int age) {
// Validate BEFORE calling super — now legal in Java 25!
if (age < 18) {
throw new IllegalArgumentException("Must be 18+");
}
super(name, age);
}
}
Primitive Types in Patterns (JEP 507) — 3rd Preview
Pattern matching now works with int, long, double, and other primitives in instanceof and switch:
Primitive Patterns in switch
// switch with int patterns — new in Java 25 (preview)
String classify(int statusCode) {
return switch (statusCode) {
case 200 -> "OK";
case 301, 302 -> "Redirect";
case 400 -> "Bad Request";
case 404 -> "Not Found";
case 500 -> "Server Error";
case int n when n >= 200 && n < 300 -> "Success";
case int n when n >= 400 && n < 500 -> "Client Error";
default -> "Unknown";
};
}
Performance & Runtime
Compact Object Headers (JEP 519) — Final
Object headers in the HotSpot JVM are reduced from 96–128 bits down to 64 bits on 64-bit architectures. This is automatic — no code changes needed.
Ahead-of-Time Method Profiling (JEP 515) — Final
Java apps typically run slow at startup while the JIT compiler “warms up” by profiling which methods are hot. JEP 515 saves those profiles from a previous run into an AOT cache, so the JIT can generate native code immediately on next startup.
AOT Cache with Method Profiles
# Create AOT cache in one step (JEP 514 simplifies this)
java -XX:AOTCacheOutput=app.aot -jar myapp.jar
# Run with cached profiles — instant warmup
java -XX:AOTCache=app.aot -jar myapp.jar
Generational Shenandoah (JEP 521) — Final
The Shenandoah garbage collector now officially supports generational mode, promoting it from experimental to production-ready.
Enable Generational Shenandoah
java -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -jar myapp.jar
Benefits: improved throughput, better load-spike resilience, and more efficient memory utilization compared to non-generational mode.
Concurrency & Data Sharing
Scoped Values (JEP 506) — Final
ScopedValue is finalized after five previews. It provides a way to share immutable data with callees within and across threads — like ThreadLocal but safer, faster, and immutable.
ScopedValue Example
private static final ScopedValue<String> USER =
ScopedValue.newInstance();
// Set the value for a scope
ScopedValue.where(USER, "admin").run(() -> {
handleRequest(); // USER.get() returns "admin" here
});
void handleRequest() {
String currentUser = USER.get(); // "admin"
// Any method called from here can also access USER
}
Structured Concurrency (JEP 505) — 5th Preview
Groups of related tasks running in different threads are treated as a single unit of work. If one subtask fails, the others are automatically cancelled.
Structured Concurrency
// Fetch user and orders in parallel — if either fails, both cancel
try (var scope = StructuredTaskScope.open()) {
Subtask<User> userTask = scope.fork(() -> fetchUser(userId));
Subtask<List<Order>> ordersTask = scope.fork(() -> fetchOrders(userId));
scope.join(); // Wait for both
return new UserProfile(userTask.get(), ordersTask.get());
}
Stable Values (JEP 502) — Preview
A StableValue can be set only once and is then treated as a constant by the JVM, enabling constant-folding optimizations. Perfect for lazy initialization.
Stable Values
// Lazy, thread-safe, one-time initialization
private static final StableValue<DatabasePool> DB_POOL =
StableValue.of(() -> createExpensivePool());
// First call initializes, all subsequent calls return the same instance
DatabasePool pool = DB_POOL.get();
Security
Key Derivation Function API (JEP 510) — Final
A new API for deriving additional cryptographic keys from a secret key. Supports HKDF (HMAC-based Extract-and-Expand) and Argon2.
Key Derivation
import javax.crypto.KDF;
KDF kdf = KDF.getInstance("HKDF-SHA256");
SecretKey derivedKey = kdf.deriveKey(
"AES",
new HKDFParameterSpec.Builder(
secretKey, salt, info
).build()
);
This is a foundational piece for Java’s post-quantum cryptography support — used internally by ML-KEM and TLS 1.3 Hybrid Key Exchange.
PEM Encodings of Cryptographic Objects (JEP 470) — Preview
A new API for encoding/decoding keys, certificates, and CRLs in the widely used PEM format (.pem files). No more bouncing between byte arrays and Base64 manually.
Observability (JFR)
Java Flight Recorder gets three significant upgrades in JDK 25:
JFR Enhancements
| JEP | Feature | What It Does |
|---|---|---|
| 518 | Cooperative Sampling | Walks call stacks only at safepoints, reducing bias and improving stability |
| 520 | Method Timing & Tracing | Records execution times for specific methods without modifying source code |
| 509 | CPU-Time Profiling (Experimental) | More accurate CPU-time capture on Linux using kernel CPU timers |
For QA teams, JFR Method Timing is especially useful — you can identify slow methods in production without adding any logging or instrumentation to your code.
Other Changes
Vector API (JEP 508) — 10th Incubator
Still incubating (waiting for Project Valhalla), but now links to native math libraries via the Foreign Function and Memory API. Auto-vectorizes Float16 operations on x64 CPUs.
Removal of 32-bit x86 Port (JEP 503)
All source code and build support for 32-bit x86 is removed. If you’re still running 32-bit Java… it’s time.
Other Notable Changes
- ZGC string deduplication now skips young, short-lived strings for better performance
- New SHAKE128-256 and SHAKE256-512 MessageDigest algorithms added
- Post-quantum cryptography (PQC) support for improved security
- Removal of the experimental Graal JIT compiler
All 18 JEPs at a Glance
| JEP | Feature | Status |
|---|---|---|
| 506 | Scoped Values | Final |
| 510 | Key Derivation Function API | Final |
| 511 | Module Import Declarations | Final |
| 512 | Compact Source Files & Instance Main Methods | Final |
| 513 | Flexible Constructor Bodies | Final |
| 519 | Compact Object Headers | Final |
| 521 | Generational Shenandoah | Final |
| 507 | Primitive Types in Patterns | 3rd Preview |
| 505 | Structured Concurrency | 5th Preview |
| 502 | Stable Values | Preview |
| 470 | PEM Encodings | Preview |
| 508 | Vector API | 10th Incubator |
| 509 | JFR CPU-Time Profiling | Experimental |
| 514 | AOT Command-Line Ergonomics | Final |
| 515 | AOT Method Profiling | Final |
| 518 | JFR Cooperative Sampling | Final |
| 520 | JFR Method Timing & Tracing | Final |
| 503 | Remove 32-bit x86 Port | Removal |