Java 25 is scheduled for release in September 2025. This release brings several significant features to the Java platform, including the finalization of Scoped Values, the introduction of Stable Values, and further refinements to Structured Concurrency. Let's explore the key features included in the Java 25 release.
Feature Classifications in Java 25
Final Features: Fully implemented, tested, and officially part of the Java SE Platform.
Preview Features: Complete but not yet permanent features available for developer feedback, requiring the
--enable-previewflag.Incubator Features: Experimental APIs distributed in separate modules.
Experimental Features: Early, potentially unstable versions of VM-level features.
Stable Values are variables that can be set only once during an application's lifetime and stay unchanged after that. They provide a standardized way to lazily initialize constants, letting the JVM optimize them just like it does with final values.
This feature solves the long-standing problem of safe lazy initialization in Java. It offers better performance than final fields (which must be initialized at creation) and better safety than double-checked locking or other lazy initialization patterns.
You can learn more about Stable Values from this Stable Values Guide.
Example:
public class EmailService { private static final StableValue<SMTPClient> smtpClient = StableValue.of(); public static void sendEmail(String to, String subject, String body) { SMTPClient client = smtpClient.orElseSet(() -> new SMTPClient(loadConfiguration())); client.send(to, subject, body); } }
This feature extends pattern matching to work with primitive types in both instanceof and switch expressions. This enhancement simplifies code that needs to match primitive types, reducing boilerplate and improving readability.
Example:
public void processValue(Object obj) { switch (obj) { case int i -> System.out.println("Integer: " + i); case long l -> System.out.println("Long: " + l); case String s -> System.out.println("String: " + s); default -> System.out.println("Unknown: " + obj); } }
Related: Pattern Matching in Java — Deep dive into pattern matching, sealed types, destructuring, and related features leading up to Java 25.
Module Import Declarations allow developers to import all the packages exported by a module with a single declaration. This simplifies working with modular libraries by significantly reducing import statement verbosity.
Example:
import module java.base; void main() throws IOException { var names = List.of("Alice", "Bob", "Charlie"); Path filePath = Paths.get("test.txt"); Files.write(filePath, names); }
This feature simplifies Java program structure for beginners by eliminating the need for explicit class declarations and static main methods in simple programs. It lowers the barrier to entry for learning Java by allowing students to write their first programs without needing to understand large amounts of boilerplate code.
Example:
void main() { System.out.println("Hello, World!"); }
Flexible Constructor Bodies allow statements to appear before an explicit constructor invocation (super(...) or this(...)). This enables cleaner initialization logic and reduces the need for repetitive code in constructors, giving developers more freedom in how they structure their object initialization.
Example:
public UserProfile(String rawUsername, String rawEmail) { // Sanitize input before calling superclass constructor var sanitizedUsername = sanitize(rawUsername); var sanitizedEmail = sanitize(rawEmail); super(sanitizedUsername, sanitizedEmail); }
This feature reduces the size of object headers in the HotSpot JVM from between 96 and 128 bits down to 64 bits on 64-bit architectures. By reducing the per-object overhead, this change reduces heap size, improves deployment density, and increases data locality.
Generational Shenandoah introduces a generational mode for the Shenandoah garbage collector. This improves performance for applications with high allocation rates by separating young and old objects, allowing for more frequent collection of short-lived objects without scanning the entire heap.
Scoped Values, now a finalized feature in Java 25, provide a safer and more structured way of sharing data within a thread and its child threads. They serve as a modern alternative to ThreadLocal.
Scoped values address the limitations of ThreadLocal (unconstrained mutability, unbounded lifetime) by providing a immutable, bounded-lifetime data sharing mechanism. It is particularly important for Virtual Threads where ThreadLocal can be expensive.
You can learn more about Scoped Values from this Scoped Values Guide.
Example:
public class UserContextDemo { public static final ScopedValue<String> userScopedVal = ScopedValue.newInstance(); public static void main(String[] args) { ScopedValue.where(userScopedVal, "Alice").run(() -> { processUserRequest(); }); } static void processUserRequest() { System.out.println("Processing for user: " + userScopedVal.get()); } }
Structured Concurrency is an API that treats groups of related tasks running in different threads as a single unit of work. This simplifies concurrent programming by eliminating common risks like thread leaks and cancellation delays, while improving reliability and observability of concurrent code.
You can learn more about Structured Concurrency from this Structured Concurrency Guide.
Example:
public void generateReport(String stockSymbol) throws InterruptedException { try (var scope = StructuredTaskScope.open()) { var stockTask = scope.fork(() -> stockRepository.getStockHolding(stockSymbol)); var marketPriceTask = scope.fork(() -> stockAPIClient.getStockPrice(stockSymbol)); scope.join(); // Process results printReport(stockTask.get(), marketPriceTask.get()); } }
The Vector API allows developers to express vector computations that reliably compile to optimal vector hardware instructions. This dramatically improves performance for computationally intensive applications by leveraging SIMD (Single Instruction, Multiple Data) hardware capabilities.
The Key Derivation Function API provides a standard API for Key Derivation Functions (KDFs). This addition provides standardized, secure methods for deriving cryptographic keys, making it easier to implement secure key management in Java applications.
This preview feature introduces a standard API for encoding and decoding cryptographic keys and certificates in the PEM format. This simplifies the handling of cryptographic artifacts, which are commonly exchanged in PEM format across different systems.
This experimental feature enhances JDK Flight Recorder (JFR) to capture more accurate CPU-time profiling information on Linux. It provides deeper insights into application performance by accurately measuring CPU consumption of individual methods, helping developers identify optimization targets more effectively.
This update extends JFR with facilities for method timing and tracing via bytecode instrumentation. It allows recording complete and exact statistics for specific methods without source code modifications, moving beyond sample-based statistics for critical code paths.
JFR Cooperative Sampling improves the stability of JFR when asynchronously sampling Java thread stacks by walking call stacks only at safepoints while minimizing safepoint bias. This enhances the reliability of profiling in production environments by preventing crashes that could occur with previous asynchronous sampling techniques.
This feature simplifies the process of creating ahead-of-time (AOT) caches by streamlining the command-line options. It makes it easier for developers to adopt AOT compilation for faster startup times without dealing with complex multi-step processes.
Ahead-of-Time Method Profiling improves warmup time by making method-execution profiles from a previous run available immediately upon startup. This enables the JIT compiler to generate native code immediately, significantly reducing the warmup period for Java applications.
JDK 25 continues the trend of modernizing Java with features that improve developer productivity, performance, and security. The finalization of Scoped Values and the introduction of Stable Values are particularly exciting for building robust, high-performance applications.
To stay updated with the latest updates in Java and Spring, follow us on LinkedIn and Medium.
Learn about Stable Values in Java 25, a preview feature that provides safe lazy initialization with thread-safety and JVM optimizations.
Learn about the Structured concurrency API in Java 25, new way to write concurrent code

Get instant AI-powered summaries of YouTube videos and websites. Save time while enhancing your learning experience.