Explore Java’s Evolution: Key New Features from JDK 10 to JDK 21
This article reviews the most important new features introduced in Java JDK 10 through JDK 21—including local‑variable type inference, the standardized HTTP client, experimental garbage collectors, pattern‑matching enhancements, records, sealed classes, and virtual threads—providing code examples and migration guidance for developers.
Java has evolved significantly from JDK 10 to JDK 21, introducing a series of language and runtime enhancements that improve performance, safety, and developer productivity.
JDK 10
Local‑variable type inference – The var keyword allows the compiler to infer the type of a local variable from its initializer.
<code>var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
var a = 100;
var str = "Hello";
var date = new Date();
</code>JDK 11
HTTP Client – The incubated HTTP client API from JDK 9 is standardized (JEP 110).
<code>HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create("http://localhost:8088/demos/format?id=1010")).GET().build();
HttpResponse<String> response = client.send(req, HttpResponse.BodyHandlers.ofString(Charset.forName("UTF-8")));
System.out.println(response.statusCode());
System.out.println(response.version().name());
System.out.println(response.body());
</code>Experimental Garbage Collectors
Epsilon GC (experimental) – A no‑op collector that only allocates memory and terminates the JVM when the heap is exhausted.
<code>-XX:+UseEpsilonGC</code>ZGC (low‑latency GC, experimental) – Targets pause times under 10 ms, supports heap sizes from hundreds of MB to TB, and aims for minimal throughput loss.
<code>-XX:+UnlockExperimentalVMOptions -XX:+UseZGC</code>Shenandoah GC (low‑pause, experimental) – Provides pause times independent of heap size.
<code>-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC</code>JDK 12
Switch expression (preview) – Allows switch to be used as an expression with arrow syntax.
<code>switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
</code>JDK 13
Text blocks (preview) – Multi‑line string literals that avoid most escape sequences.
<code>String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
</code>JDK 14
Pattern matching for instanceof (preview) – Simplifies type checks and casts.
<code>if (ap instanceof Person person) {
System.out.println(person);
}
</code>Records (preview) – Concise syntax for immutable data carriers.
<code>public record PersonRecord(String name, Integer age) {
public PersonRecord {
if (age < 0) throw new IllegalArgumentException("Invalid age");
}
}
PersonRecord p = new PersonRecord("Zhang San", 12);
System.out.println(p);
</code>JDK 15
Sealed classes (preview) – Restricts which classes may extend or implement a class/interface.
<code>public sealed class Animal permits Dog {}
public final class Dog extends Animal {}
</code>Deprecates the ParallelScavenge + SerialOld GC combination and disables biased locking by default.
JDK 16
Pattern matching for instanceof becomes a standard feature, and records are finalized.
JDK 17
Sealed classes are finalized, the Applet API is removed, and switch pattern matching (preview) adds when clauses to switch cases.
<code>static String formatterPatternSwitch(Object o) {
return switch (o) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> o.toString();
};
}
</code>JDK 18
Sets UTF‑8 as the default charset for the Java API and introduces jwebserver , a minimal static‑file web server.
<code>jwebserver -p 9000 # set port
jwebserver -b 0.0.0.0 # bind to all interfaces
jwebserver -d D:\www # serve directory D:\www
</code>JDK 19‑20
Preview features include record patterns, virtual threads, and continued switch pattern‑matching enhancements.
JDK 21
Virtual threads become a standard feature, dramatically increasing throughput. Switch pattern matching now supports when clauses, and record patterns are finalized.
<code>static void testStringNew(String response) {
switch (response) {
case null -> {}
case String s when s.equalsIgnoreCase("YES") -> System.out.println("You got it");
case String s when s.equalsIgnoreCase("NO") -> System.out.println("Shame");
case String s -> System.out.println("Sorry?");
}
}
</code>These updates collectively enhance Java’s expressiveness, performance, and ease of use for modern application development.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.