Java 21 Features: A Complete Beginner-Friendly Breakdown
Java 21 is a landmark release as it’s a Long-Term Support (LTS) version, packed with features that significantly improve developer productivity and application performance. In this guide, we’ll explore the most important features with clear explanations and visual diagrams to help you understand how they work.
Key Takeaways
- Virtual Threads revolutionize concurrency with lightweight threads
- Records provide concise syntax for immutable data carriers
- Pattern Matching simplifies conditional extraction of data from objects
- Sequenced Collections bring predictable iteration order
- String Templates simplify string formatting and interpolation
Virtual Threads (JEP 444)
Lightweight threads that dramatically reduce the effort of writing, maintaining, and debugging concurrent applications
Virtual threads are lightweight threads that help to write high-throughput concurrent applications with the simple thread-per-request style. They’re managed by the JVM rather than the operating system, making them cheap to create and efficient to use.
Virtual threads are mounted on platform threads. When a virtual thread blocks, the platform thread can run another virtual thread.
Traditional platform threads are expensive to create and context-switch because they’re mapped 1:1 to OS threads. Virtual threads are managed by the JVM, allowing you to have millions of threads without overwhelming the system.
Code Example
Records (JEP 440)
Transparent carriers for immutable data with automatically derived methods
Records provide a compact syntax for declaring classes that are transparent holders for shallowly immutable data. They automatically generate boilerplate code like constructors, accessors, equals(), hashCode(), and toString().
String name,
int age,
String email
) {}
Traditional Class vs Record
| Traditional Class | Record |
|---|---|
| 50+ lines of code for a simple data carrier | 1 line of code |
| Manually implement equals(), hashCode(), toString() | Automatically generated |
| Mutable by default | Immutable by design |
| Verbose constructor | Compact canonical constructor |
Code Example
public class PersonClass { private final String name; private final int age; // Constructor, getters, equals, hashCode, toString… }
// Record (Java 21)
public record Person(String name, int age, String email) { // Compact constructor with validation public Person { if (age < 0) { throw new IllegalArgumentException(“Age cannot be negative”); } } }
// Usage
Person person = new Person(“Alice”, 30, “[email protected]”); System.out.println(person.name()); // Accessor: name() not getName() System.out.println(person); // Auto-generated toString()
Pattern Matching (JEP 441)
Simplify conditional extraction of components from objects
Pattern matching allows you to conditionally extract components from objects with a single, concise syntax. It extends the instanceof operator to declare a pattern variable and automatically casts it.
Evolution of Pattern Matching in Java
| Java Version | Pattern Matching Capability |
|---|---|
| Before Java 16 | Manual instanceof checks with explicit casting |
| Java 16 | Pattern matching for instanceof |
| Java 17 | Pattern matching for switch (preview) |
| Java 21 | Pattern matching for switch (final) |
Code Example
if (shape instanceof Circle) { Circle circle = (Circle) shape; System.out.println(“Radius: “ + circle.getRadius()); } else if (shape instanceof Rectangle) { Rectangle rect = (Rectangle) shape; System.out.println(“Area: “ + rect.getWidth() * rect.getHeight()); }
// New way: Pattern matching with switch
switch (shape) { case Circle c when c.getRadius() > 0 -> System.out.println(“Circle with radius: “ + c.getRadius()); case Rectangle r -> System.out.println(“Rectangle area: “ + r.getWidth() * r.getHeight()); case null -> System.out.println(“Shape is null”); default -> System.out.println(“Unknown shape”); }
// Record patterns – destructuring records
if (obj instanceof Point(int x, int y)) { System.out.println(“Point at (“ + x + “, “ + y + “)”); }
Other Notable Features in Java 21
Sequenced Collections
New interfaces to represent collections with a defined encounter order. Provides uniform APIs for accessing first and last elements.
String Templates
Simplify string interpolation and composition with embedded expressions. Safer than concatenation or StringBuilder.
Scoped Values
Share immutable data within and across threads. Better alternative to ThreadLocal for virtual threads.
