๐Ÿ‡ฎ๐Ÿ‡ณ
๐Ÿ‡ฎ๐Ÿ‡ณ
Limited-Time Offer!Get 20% OFF on all live courses
Enroll Now
PrakalpanaLive online tech training
Java Ecosystemโฑ๏ธ 12 min read๐Ÿ“… Oct 1

Java 21 Features Explained (and What's New up to Java 25)

AN
Arjun Nairโ€ขSenior Backend Engineer
๐Ÿ“‘ Contents (19 sections)

๐Ÿ“ŒWhy Java 21 Matters

Java 21 is a long-term support (LTS) release, and with Java 25 (the next LTS, September 2025) it is what new enterprise projects target in 2026. Spring Boot 3 requires Java 17 as a minimum and runs best on 21 or 25. If you learned Java 8, the language has changed more in the last few releases than in the decade before. This guide covers the features you will actually use โ€” and that interviewers now ask about.

New to Java altogether? Our live Java course teaches modern Java from day one.

๐Ÿ“Œ1. Records (Java 16)

A record is a concise, immutable data carrier. The compiler generates the constructor, accessors, equals(), hashCode() and toString().

public record Employee(String name, String department, double salary) {
public Employee {
if (salary < 0) throw new IllegalArgumentException("salary must be positive");
}
}
var e = new Employee("Asha", "Engineering", 1_800_000);
System.out.println(e.name()); // Asha

Use records for DTOs, API requests and responses, and value objects. They work well with Spring Boot and Jackson.

๐Ÿ“Œ2. Text Blocks (Java 15)

Multi-line strings without escape noise โ€” perfect for SQL, JSON and HTML.

String query = """
SELECT id, name
FROM employees
WHERE department = ?
ORDER BY name
""";

๐Ÿ“Œ3. Sealed Classes and Interfaces (Java 17)

Sealed types restrict which classes can extend them, so the compiler knows every possible subtype.

public sealed interface Shape permits Circle, Rectangle, Square {}
public record Circle(double radius) implements Shape {}
public record Rectangle(double width, double height) implements Shape {}
public record Square(double side) implements Shape {}

๐Ÿ“Œ4. Pattern Matching for instanceof (Java 16)

if (obj instanceof String s && !s.isBlank()) {
System.out.println(s.length());
}

No more casting after the check.

๐Ÿ“Œ5. Switch Expressions (Java 14)

int days = switch (month) {
case FEBRUARY -> 28;
case APRIL, JUNE, SEPTEMBER, NOVEMBER -> 30;
default -> 31;
};

Arrow labels do not fall through, and the switch returns a value.

๐Ÿ“Œ6. Pattern Matching for switch (Java 21)

Combine sealed types, records and switch for exhaustive, type-safe logic:

static double area(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.width() * r.height();
case Square s -> s.side() * s.side();
};
}

Because Shape is sealed, no default is needed โ€” and if you add a new shape, every switch that misses it fails to compile. Guards refine cases:

String describe(Object o) {
return switch (o) {
case null -> "null";
case Integer i when i > 100 -> "big number";
case Integer i -> "number " + i;
case String s -> "text of length " + s.length();
default -> "something else";
};
}

๐Ÿ“Œ7. Record Patterns (Java 21)

Deconstruct records directly in patterns, including nested ones:

record Point(int x, int y) {}
record Line(Point start, Point end) {}
static String classify(Object o) {
return switch (o) {
case Line(Point(var x1, var y1), Point(var x2, var y2)) when x1 == x2 -> "vertical line";
case Line(Point s, Point e) -> "line from " + s + " to " + e;
default -> "unknown";
};
}

๐Ÿ“Œ8. Virtual Threads (Java 21)

The headline feature. Virtual threads are lightweight threads scheduled by the JVM onto a small pool of OS carrier threads. Blocking I/O parks the virtual thread instead of an OS thread, so a server can handle hundreds of thousands of concurrent requests with simple, blocking code.

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 100_000).forEach(i ->
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
}));
}

In Spring Boot 3.2+, one property switches Tomcat and task executors to virtual threads:

spring.threads.virtual.enabled=true

Best for I/O-bound work (HTTP calls, database queries). They do not speed up CPU-bound work. Before Java 24, blocking inside synchronized blocks pinned the carrier thread; JEP 491 in Java 24 removed most of that pinning.

๐Ÿ“Œ9. Sequenced Collections (Java 21)

Ordered collections finally have a common API:

List<String> names = new ArrayList<>(List.of("a", "b", "c"));
names.getFirst(); // "a"
names.getLast(); // "c"
names.reversed(); // [c, b, a]
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.putFirst("x", 1);
map.firstEntry();

๐Ÿ“Œ10. Other Useful Additions

  • var for local variables (Java 10) โ€” less boilerplate, still statically typed
  • Helpful NullPointerExceptions (Java 14) โ€” messages name the exact null variable
  • Stream.toList() (Java 16) โ€” an unmodifiable list without collect(Collectors.toList())
  • Generational ZGC (Java 21) โ€” very low GC pauses with better throughput
  • String templates were previewed in 21 and 22 but then withdrawn โ€” do not use them
  • ๐Ÿ“ŒWhat's New After Java 21, up to Java 25

    Java 25 is the next LTS. Highlights that became final between 22 and 25:

  • Unnamed variables and patterns (Java 22) โ€” use _ for values you do not need: case Point(var x, _) ->
  • Foreign Function and Memory API (Java 22) โ€” a safe, fast replacement for JNI
  • Stream gatherers (Java 24) โ€” custom intermediate stream operations such as sliding windows
  • Virtual threads without synchronized pinning (Java 24)
  • Scoped values (Java 25) โ€” a safer, faster alternative to ThreadLocal, especially with virtual threads
  • Module import declarations (Java 25) โ€” import module java.base;
  • Compact source files and instance main methods (Java 25) โ€” void main() { ... } for simple programs and scripts
  • Flexible constructor bodies (Java 25) โ€” statements before super(...)
  • Compact object headers (Java 25) โ€” smaller object headers, reducing memory usage
  • Structured concurrency remains in preview and is worth watching.

    ๐Ÿ“ŒMigrating From Java 8 or 11 to Java 21

    Most migrations are smoother than teams expect. A practical sequence:

  • 1Upgrade build tools first โ€” a recent Maven or Gradle, plus compiler, Surefire and plugin versions that support Java 21
  • 2Upgrade frameworks โ€” Spring Boot 3 needs Java 17+ and moves from javax.* to jakarta.* packages; tools such as OpenRewrite automate most of that rename
  • 3Fix removed APIs โ€” Java EE modules (JAXB, JAX-WS) left the JDK in Java 11 and must be added as dependencies
  • 4Check strong encapsulation โ€” libraries that reflect into JDK internals may need upgrades instead of --add-opens flags
  • 5Run the full test suite, then load-test โ€” and compare GC behaviour, since G1 defaults and container awareness have improved significantly
  • Then adopt new language features gradually: records for new DTOs, pattern matching where it simplifies instanceof chains, and virtual threads for I/O-heavy services after measuring.

    ๐Ÿ“ŒFrequently Asked Questions

    Are virtual threads a replacement for reactive programming?

    For most request-per-thread web services, yes โ€” they deliver similar scalability with simple, blocking code that is easier to read, debug and profile. Reactive libraries remain useful for streaming, backpressure and complex asynchronous composition.

    Do records replace Lombok?

    For immutable data carriers, largely yes. Records do not suit JPA entities, which need a no-argument constructor and mutable fields, so many projects still use Lombok or plain getters and setters for entities.

    Should I pool virtual threads?

    No. Virtual threads are cheap to create, so create one per task. If you need to limit concurrency โ€” for example, calls to a rate-limited API โ€” use a Semaphore rather than a fixed-size pool.

    ๐Ÿ“ŒWhich Version Should You Use?

    For new projects in 2026, target Java 21 or Java 25 with Spring Boot 3. Both are LTS releases supported by every major vendor. Migrating from Java 8 or 11 to 21 is usually straightforward, and the performance and memory gains alone often justify it.

    ๐Ÿ“ŒPractise Modern Java

    Interviewers now expect these features โ€” see our Java interview questions and the Java developer roadmap. Then put them to work in a Spring Boot REST API.

    Prakalpana's Java Programming course teaches modern Java (21/25) live online with an optional 1-on-1 track and real projects. WhatsApp or call +91 9243078181 for a free demo.

    AN

    Written by

    Arjun Nair

    Senior Backend Engineer

    ๐Ÿš€ Master Java Ecosystem

    Live online + 1-on-1 Java Programming training ยท Join 5000+ developers