Fundamentals 15 min read

What Changed in Java 21? A Complete API Comparison for Upgrading from Java 17

This article provides a detailed comparison of Java 17 and Java 21 APIs, listing deprecated and removed features, suggested replacements, new I/O and serialization capabilities, enhanced reflection, Unicode emoji support, the preview foreign memory API, and the Generational ZGC, illustrated with real‑world code examples and usage scenarios.

JakartaEE China Community
JakartaEE China Community
JakartaEE China Community
What Changed in Java 21? A Complete API Comparison for Upgrading from Java 17

Key API Changes from Java 17 to Java 21

Java 21 (LTS, released 19 Sep 2023) deprecates or removes several APIs that were present in Java 17 and adds new capabilities.

Deprecated and Removed APIs

ObjectOutputStream.PutField – no direct replacement; custom serialization or third‑party libraries such as Kryo may be used.

ObjectOutput.write(Object) – marked for removal; alternatives are ObjectOutputStream.writeObject(Object) or writeUnshared(Object).

Enum.finalize(), Runtime.runFinalization(), System.runFinalization(), ThreadDeath – deprecated and marked for removal; finalization should be avoided in favor of try‑with‑resources.

Runtime.exec(...), Runtime.exec(String, String[]), Runtime.exec(String, String[], File) – deprecated; replace with ProcessBuilder.

Thread.getId() – deprecated; use Thread.currentThread().getName() and Thread.currentThread().isAlive() for identification and liveness checks.

All URL constructors that take separate components (e.g., new URL(String), new URL(String, String, int, String), etc.) – deprecated; construct URLs via URI or new URL(String, ClassLoader) when a specific class loader is required.

java.security.spec.PSSParameterSpec.DEFAULT and related constructors – deprecated.

MemoryMXBean.getObjectPendingFinalizationCount() – deprecated.

Removed classes: ClassSpecializer.Factory, ClassSpecializer.SpeciesData, Compiler, several FdLibm math functions, MLet‑related classes, and RMI connector classes.

Replacement Guidance

ProcessBuilder example:

ProcessBuilder pb = new ProcessBuilder(command, arguments);
Process p = pb.start();
// handle I/O streams as needed

Thread identification :

String name = Thread.currentThread().getName();
boolean alive = Thread.currentThread().isAlive();

URL with class loader :

URL url = new URL("https://example.com/", MyClassLoader.class.getClassLoader());

New Features

InputStream.transferTo(OutputStream)

– zero‑copy transfer, also added to FileInputStream and SequenceInputStream.

Console class changed from final to sealed, allowing controlled subclassing. PrintStream.charset() – returns the charset used by the stream.

Serialization: new constructors for InvalidClassException and InvalidObjectException; ObjectInputStream.GetField.get(String, Object) now throws ClassNotFoundException.

Reflection: Executable, Field, and Parameter now expose accessFlags() to retrieve runtime access modifiers.

Unicode/Emoji support in Character: isEmoji(int), isEmojiComponent(int), isEmojiPresentation(int).

Foreign Function & Memory API (preview) in package java.lang.foreign simplifies native calls and off‑heap memory management.

Usage Scenarios

Scenario 1 – Efficient Data Transfer in Network Applications

Transfer a large file from a server to a client without intermediate buffers using transferTo:

import java.io.*;
import java.net.*;

public class FileServer {
    public static void main(String[] args) throws IOException {
        try (ServerSocket ss = new ServerSocket(8080);
             Socket client = ss.accept();
             BufferedInputStream in = new BufferedInputStream(new FileInputStream("largeFile.bin"));
             OutputStream out = client.getOutputStream()) {
            in.transferTo(out);
            System.out.println("File transferred successfully.");
        }
    }
}

This approach eliminates the copy‑to‑byte‑array step, reducing CPU usage and latency.

Scenario 2 – Advanced Debugging with Reflection Access Flags

Inspect method modifiers at runtime:

import java.lang.reflect.*;

public class ReflectInspector {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> cls = Class.forName("MyClass");
        for (Method m : cls.getDeclaredMethods()) {
            int flags = m.getModifiers(); // accessFlags() is exposed via getModifiers()
            System.out.printf("Method: %s, Access Flags: %s%n", m.getName(), Modifier.toString(flags));
        }
    }
}

Scenario 3 – Internationalization & Emoji Handling

Detect emoji code points in a string:

String comment = "Hello 🌍!";
comment.codePoints().forEach(cp -> {
    if (Character.isEmoji(cp)) {
        System.out.printf("Found emoji: %s%n", new String(Character.toChars(cp)));
    }
});

Generational ZGC (Garbage Collector)

Generational ZGC introduces a young/old generation split based on the “weak generational hypothesis”. Internal benchmarks show roughly a 10 % throughput improvement over the single‑generation ZGC and reduced pause times for high‑throughput workloads. It is enabled via JVM flags (e.g., -XX:+UseZGC -XX:+ZGenerational) and is expected to become the default in a future release.

Conclusion

Upgrading from Java 17 to Java 21 provides zero‑copy I/O, richer serialization diagnostics, enhanced reflection, comprehensive Unicode/emoji handling, a preview foreign‑memory API, and a more efficient Generational ZGC. Understanding the deprecated APIs, their replacements, and the new capabilities enables developers to modernize codebases and achieve measurable performance and maintainability gains.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaPerformanceReflectionserializationGarbage Collectionjava-21api-changesdeprecation
JakartaEE China Community
Written by

JakartaEE China Community

JakartaEE China Community, official website: jakarta.ee/zh/community/china; gitee.com/jakarta-ee-china; space.bilibili.com/518946941; reply "Join group" to get QR code

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.