Skip to content

Java 24

Neelu edited this page Jul 26, 2026 · 1 revision

☕ Java 24: Stream Gatherers Standard & Class-File API Standard

Release Date: March 18, 2025 | Type: Standard (non-LTS) | Status: ⚠️ End of Life (superseded by Java 25 LTS)

⚠️ Note: This guide was written from JEP proposals as of early 2025. Since Java 24 was released after that point, verify exact final feature status against the official release notes before relying on specifics like JEP numbers or preview/standard status.


📋 Table of Contents

  1. Overview
  2. Core Features
  3. Best Practices

🎯 Overview

Java 24 continues consolidating the concurrency and pattern-matching work from Loom/Amber, standardizes Stream Gatherers and the Class-File API, and takes a major step in JVM security posture by finishing the removal of the legacy Security Manager.

flowchart LR
    A["Java 22: Stream Gatherers Preview"] --> B["Java 23: 2nd Preview"] --> C["Java 24: STANDARD ✅"]
    D["Java 22: Class-File API Preview"] --> E["Java 23: 2nd Preview"] --> F["Java 24: STANDARD ✅"]
Loading

🚀 Core Features

1️⃣ Stream Gatherers (Standard)

import static java.util.stream.Gatherers.*;

// Sliding window — finalized API
List<List<Integer>> windows = Stream.of(1, 2, 3, 4, 5)
    .gather(windowSliding(2))
    .toList();
// [[1,2], [2,3], [3,4], [4,5]]

// Fixed batching for chunked processing (e.g., batch DB inserts)
orderIds.stream()
    .gather(windowFixed(500))
    .forEach(batch -> batchInsert(batch));

// Custom gatherer — write your own intermediate stream operation
Gatherer<Integer, ?, Integer> distinctByEvenOdd = Gatherer.of(
    () -> new HashSet<Integer>(),                          // initializer
    (state, element, downstream) -> {                       // integrator
        if (state.add(element % 2)) {
            downstream.push(element);
        }
        return true;
    }
);
List<Integer> result = Stream.of(1, 2, 3, 4, 5, 6)
    .gather(distinctByEvenOdd)
    .toList(); // [1, 2] — first odd, first even

See the Java 22 guide for the original motivation.


2️⃣ Class-File API (Standard)

What: A standard, versioned API for parsing and generating .class files — replacing the JDK's internal use of ASM for tools like javac, jlink, and various frameworks.

import java.lang.classfile.*;

// Parse an existing class file
ClassModel classModel = ClassFile.of().parse(classBytes);
classModel.methods().forEach(method ->
    System.out.println(method.methodName().stringValue())
);

// Generate bytecode programmatically — mainly relevant to
// framework/library authors building proxies, instrumentation, etc.

Why it matters: Library authors (bytecode manipulation, AOT tooling, instrumentation frameworks) no longer need to bundle/shade a specific ASM version that must track JDK bytecode format changes — the JDK now ships its own always-in-sync API.


3️⃣ Ahead-of-Time Class Loading & Linking (JEP 483)

What: Improves on AppCDS by capturing a fully-linked set of classes ready to load, further cutting startup time for large applications.

# Create an AOT cache during a training run
java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -jar app.jar

# Create the AOT cache from the recorded configuration
java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -cp app.jar

# Use it for faster subsequent startups
java -XX:AOTCache=app.aot -cp app.jar Main

4️⃣ Synchronize Virtual Threads Without Pinning (JEP 491)

What: Fixes the Java 21-era synchronized pinning problem — synchronized blocks no longer pin virtual threads to their carrier during blocking operations.

// On Java 21-23, this pinned the carrier thread during the blocking call
synchronized (lock) {
    String result = blockingHttpCall();
}

// On Java 24+, this is FINE — no pinning, virtual thread unmounts normally
// (Prior guidance to prefer ReentrantLock over synchronized for this reason
// becomes less critical, though ReentrantLock offers other benefits too)
flowchart LR
    A["Java 21-23:\nsynchronized + blocking I/O"] -->|Pins carrier thread| B["❌ Reduced scalability"]
    C["Java 24+:\nsynchronized + blocking I/O"] -->|No pinning| D["✅ Full virtual thread benefits"]
Loading

5️⃣ Quantum-Resistant Cryptographic Algorithms (JEP 496, 497)

What: Adds ML-KEM (key encapsulation) and ML-DSA (digital signatures) — NIST-standardized post-quantum cryptography algorithms, built into the JDK's security providers.

// Illustrative — exact API surface should be verified against release docs
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA");
KeyPair keyPair = kpg.generateKeyPair();

Signature signature = Signature.getInstance("ML-DSA");
signature.initSign(keyPair.getPrivate());
signature.update(message);
byte[] sig = signature.sign();

Why it matters: Prepares Java applications for a future where quantum computers could break traditional RSA/ECC cryptography — relevant now for systems with long-lived data confidentiality requirements.


6️⃣ Security Manager — Fully Removed

The Security Manager (deprecated since Java 17) is fully removed. Any code still calling System.getSecurityManager() or relying on AccessController must be migrated.


7️⃣ Simple Source Files & Instance Main Methods (continued preview)

// Simplified "scripting style" entry point — no class boilerplate needed
void main() {
    System.out.println("Hello from a simplified main!");
}

// Runs directly:
// java HelloWorld.java

💡 Best Practices

✅ Use Stream Gatherers for windowing/batching now that the API is stable — safe for production use
✅ Re-evaluate synchronized vs ReentrantLock decisions made for virtual-thread pinning — Java 24 removes the main reason to avoid synchronized
✅ Audit for any remaining SecurityManager usage before upgrading — it's a hard removal, not a deprecation warning
❌ Don't assume every JEP mentioned here is final/standard without checking release notes — several were still in preview as of this guide's writing


Clone this wiki locally