Java Evolution
Major features introduced in Java 5, 8, 11, 17, and 21
Java has evolved dramatically since its release in 1995. Each major LTS version introduced features that fundamentally changed how we write Java code. Knowing which feature came in which version is essential for interviews and for understanding legacy codebases versus modern Java.
Key Points
- Java 5 (2004): Generics, Enums, Annotations, Autoboxing, Enhanced for-loop, varargs — transformed the language
- Java 8 (2014): Lambdas + Stream API, Default/static interface methods, Optional, new Date/Time API (java.time) — the biggest release since Java 5
- Java 11 (2018 LTS): var in lambda params, String.isBlank/strip/lines/repeat, Files.readString/writeString, new HttpClient API, removal of Java EE modules
- Java 17 (2021 LTS): Sealed classes (final), Records (final — immutable data carriers), Pattern matching for instanceof (final), Text Blocks (final)
- Java 21 (2023 LTS): Virtual Threads / Project Loom (final), Sequenced Collections, Record Patterns (final), Pattern Matching for switch (final)
- LTS releases (8, 11, 17, 21) get multi-year support — most enterprises target LTS versions
- var (Java 10): local variable type inference — compiler infers type from initializer
| Version | Year | Key Features |
|---|---|---|
| Java 5 | 2004 | Generics, Enums, Annotations, Autoboxing, Enhanced for, varargs |
| Java 7 | 2011 | Try-with-resources, Diamond operator <>, Switch on Strings, NIO.2 |
| Java 8 LTS | 2014 | Lambdas, Streams, Optional, Default methods, java.time, Nashorn JS |
| Java 9 | 2017 | Module system (JPMS), JShell REPL, List/Set/Map.of(), private interface methods |
| Java 10 | 2018 | var (local type inference), G1 parallel full GC, Application CDS |
| Java 11 LTS | 2018 | HttpClient, String methods, var in lambdas, removal of CORBA/Java EE |
| Java 14 | 2020 | Records (preview), Pattern instanceof (preview), Switch expressions (final), helpful NPE messages |
| Java 15 | 2020 | Sealed classes (preview), Text Blocks (final), ZGC production-ready |
| Java 16 | 2021 | Records (final), Pattern instanceof (final), Stream.toList() |
| Java 17 LTS | 2021 | Sealed classes (final), Pattern matching switch (preview), strong encapsulation of JDK internals |
| Java 19 | 2022 | Virtual Threads (preview), Structured Concurrency (incubator) |
| Java 21 LTS | 2023 | Virtual Threads (final), Sequenced Collections, Record Patterns (final), Switch Patterns (final) |
Evolution from Java 8 Streams through Records, Sealed Classes, to Java 21 Virtual Threads
// Java 8 — Lambdas & Streams
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream()
.filter(n -> n.length() > 3)
.map(String::toUpperCase)
.forEach(System.out::println);
// Java 14 — Records (final in Java 16)
record Point(int x, int y) {}
var p = new Point(3, 4); // var from Java 10
// Java 17 — Sealed classes + pattern switch (final in Java 21)
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double w, double h) implements Shape {}
double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.w() * r.h();
};
}
// Java 21 — Virtual Threads
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> System.out.println("Running on: " + Thread.currentThread()));
}Real-World Example
Upgrading from Java 8 to 17 is the most common enterprise migration today. Key blockers: removal of Java EE APIs (use Jakarta EE dependencies instead), strong encapsulation of JDK internals (--add-opens flags), and Nashorn JS engine removal. Java 21 virtual threads are a drop-in for thread-per-request servers — the same code runs with 10x more throughput.