Java 8 to Java 21 Features - Explained
Clearly
Java 8 - Lambda Expressions
👉 WHY INTRODUCED:
To reduce boilerplate and introduce functional programming into Java. Anonymous
classes were too verbose.
📌 WHERE USED:
Used in event handling, filtering data, multi-threading (Runnable), sorting.
💡 REAL-TIME EXAMPLE:
List<String> names = Arrays.asList("Raj", "Ravi", "Ram");
names.sort((s1, s2) -> s1.compareTo(s2));
Java 9 - JShell
👉 WHY INTRODUCED:
To allow interactive execution of Java code for learning and testing quickly.
📌 WHERE USED:
Used in learning environments, testing logic without writing full classes.
💡 REAL-TIME EXAMPLE:
jshell> int a = 5;
jshell> int b = 10;
jshell> a + b
Output: 15
Java 10 - var Keyword
👉 WHY INTRODUCED:
To simplify local variable declarations when the type is clear, reducing verbosity.
📌 WHERE USED:
Used in local variables, loop variables, try-with-resources.
💡 REAL-TIME EXAMPLE:
var name = "Ranganath"; // Inferred as String
var list = new ArrayList<String>(); // Inferred as ArrayList<String>
Java 11 - New String Methods
👉 WHY INTRODUCED:
To make common string operations easier like blank check, line splitting, and repetition.
📌 WHERE USED:
Used in input validation, text parsing, formatting.
💡 REAL-TIME EXAMPLE:
System.out.println(" ".isBlank()); // true
"Hello\nWorld".lines().forEach(System.out::println);
System.out.println("Ha".repeat(3)); // HaHaHa
Java 12 - Switch Expressions (Preview)
👉 WHY INTRODUCED:
To reduce the verbosity and increase clarity in switch-case blocks.
📌 WHERE USED:
Used in decision making where switch returns a value.
💡 REAL-TIME EXAMPLE:
int day = 2;
String result = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
default -> "Other";
};
System.out.println(result);
Java 13 - Text Blocks (Preview)
👉 WHY INTRODUCED:
To simplify writing multi-line strings without using escape sequences and + operators.
📌 WHERE USED:
Used for HTML, XML, SQL queries, JSON, and readable configuration strings.
💡 REAL-TIME EXAMPLE:
String html = """
<html>
<body>Hello, Ranganath</body>
</html>
""";
Java 14 - Records (Preview)
👉 WHY INTRODUCED:
To create immutable data classes with less code (automatic getters, constructor,
toString, equals).
📌 WHERE USED:
Used in DTOs, API Responses, Configuration Objects.
💡 REAL-TIME EXAMPLE:
record Person(String name, int age) {}
Person p = new Person("Ranganath", 25);
System.out.println(p.name());
Java 14 - Pattern Matching for instanceof (Preview)
👉 WHY INTRODUCED:
To reduce type casting code after instanceof checks.
📌 WHERE USED:
Used when doing object type checks and casting.
💡 REAL-TIME EXAMPLE:
if (obj instanceof String s) {
System.out.println(s.toUpperCase());
}
Java 15 - Sealed Classes (Preview)
👉 WHY INTRODUCED:
To control which classes are allowed to extend a superclass.
📌 WHERE USED:
Used in domain modeling and inheritance restriction.
💡 REAL-TIME EXAMPLE:
sealed class Shape permits Circle, Square {}
final class Circle extends Shape {}
final class Square extends Shape {}
Java 16 - Records (Standard)
👉 WHY INTRODUCED:
Records became standard after preview in Java 14, offering concise immutable data
holders.
📌 WHERE USED:
Used in modern Java applications where value classes are needed.
💡 REAL-TIME EXAMPLE:
record Book(String title, String author) {}
Book b = new Book("Java", "Gosling");
Java 17 - Pattern Matching for switch (Preview)
👉 WHY INTRODUCED:
To simplify switch statements with type patterns.
📌 WHERE USED:
Used in multi-type checks with streamlined syntax.
💡 REAL-TIME EXAMPLE:
switch (obj) {
case Integer i -> System.out.println("int: " + i);
case String s -> System.out.println("String: " + s);
}
Java 21 - Virtual Threads (Final)
👉 WHY INTRODUCED:
To support high-performance concurrency by creating millions of lightweight threads.
📌 WHERE USED:
Used in web servers, APIs, microservices.
💡 REAL-TIME EXAMPLE:
Runnable task = () -> System.out.println(Thread.currentThread());
Thread.startVirtualThread(task);
Java 21 - String Templates (Preview)
👉 WHY INTRODUCED:
To safely and easily build formatted strings with placeholders.
📌 WHERE USED:
Used in dynamic message construction, logs, emails.
💡 REAL-TIME EXAMPLE:
String name = "Ranganath";
String message = STR."Hello, \{name}!";
Java 21 - Record Patterns (Final)
👉 WHY INTRODUCED:
To destructure record objects directly in pattern matching.
📌 WHERE USED:
Used in concise data extraction from records.
💡 REAL-TIME EXAMPLE:
record Point(int x, int y) {}
Point p = new Point(5, 10);
if (p instanceof Point(int x, int y)) {
System.out.println(x + ", " + y);
}