What’s New in Java 21? Modern Features Explained (Beginner Guide)
A beginner-friendly tour of Java 21 (LTS) highlights: virtual threads, records, pattern matching and switch expressions, text blocks, and helpful NullPointerExceptions.
Java isn't the verbose, dated language many people imagine — it's evolved enormously, and modern versions are genuinely pleasant to write. Java 21 (a Long-Term Support release) brought some of the biggest improvements in years. This guide tours the highlights in plain English, so you know what modern Java looks like and can use these features to write cleaner code.
1. Virtual Threads — the headline feature
The biggest change: virtual threads make it possible to run millions of lightweight threads, dramatically simplifying high-concurrency code. Traditional threads are expensive (each maps to an OS thread); virtual threads are cheap and managed by the JVM. This is a game-changer for servers handling many simultaneous requests — and it needs almost no code change. (Full guide: virtual threads.)
// starting a virtual thread — nearly free to create Thread.startVirtualThread(() -> { System.out.println("Running on a virtual thread!"); });
2. Records — concise data classes
A record lets you declare an immutable data class in one line, instead of dozens of lines of boilerplate (constructor, getters, equals, hashCode, toString). Introduced earlier and now firmly standard:
// this ONE line replaces ~40 lines of a traditional class record Point(int x, int y) { } Point p = new Point(3, 4); p.x(); // auto-generated accessor → 3
(Full guide: Java records.)
3. Pattern matching & switch improvements
Modern switch is far more powerful — it's an expression that returns a value, and it supports pattern matching so you can branch on an object's type cleanly:
String describe(Object obj) {
return switch (obj) {
case Integer i -> "an int: " + i;
case String s -> "a string: " + s;
case null -> "nothing";
default -> "something else";
};
}
No more casting after an instanceof check — the pattern binds the variable for you. (Related: sealed classes & pattern matching.)
4. Text blocks — multi-line strings
Writing multi-line strings (JSON, SQL, HTML) used to be painful with escaped quotes and \n. Text blocks (triple quotes) make them clean:
String json = """ { "name": "Alice", "age": 30 } """; // readable, no escaping
5. Helpful NullPointerExceptions
Modern Java's NPE messages now tell you exactly which variable was null ("Cannot invoke ... because 'name' is null") — a small change that saves real debugging time.
Honestly, modern Java surprised me — I'd absorbed the stereotype that it was clunky and verbose, then features like records and text blocks made a lot of my old boilerplate simply disappear. The mental shift worth making is to stop writing "old-style" Java out of habit: reach for a record instead of a hand-written data class, use switch expressions with pattern matching, and write multi-line strings as text blocks. Your code gets shorter and clearer. You don't need to chase every version number — just know these tools exist and use them. Modern Java is a genuinely nice language to write, and these features are why.