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
VersionYearKey Features
Java 52004Generics, Enums, Annotations, Autoboxing, Enhanced for, varargs
Java 72011Try-with-resources, Diamond operator <>, Switch on Strings, NIO.2
Java 8 LTS2014Lambdas, Streams, Optional, Default methods, java.time, Nashorn JS
Java 92017Module system (JPMS), JShell REPL, List/Set/Map.of(), private interface methods
Java 102018var (local type inference), G1 parallel full GC, Application CDS
Java 11 LTS2018HttpClient, String methods, var in lambdas, removal of CORBA/Java EE
Java 142020Records (preview), Pattern instanceof (preview), Switch expressions (final), helpful NPE messages
Java 152020Sealed classes (preview), Text Blocks (final), ZGC production-ready
Java 162021Records (final), Pattern instanceof (final), Stream.toList()
Java 17 LTS2021Sealed classes (final), Pattern matching switch (preview), strong encapsulation of JDK internals
Java 192022Virtual Threads (preview), Structured Concurrency (incubator)
Java 21 LTS2023Virtual 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.