version-wise comparison of Java features from Java 8 to Java 21, including code examples for each major feature:
Try-With-Resources Statement
Feature: Automatically closes resources like files, sockets, etc., without requiring explicit finally blocks.
Example:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Diamond Operator
Feature: Simplifies the instantiation of generic classes by inferring the type arguments.
import java.util.ArrayList;
import java.util.List;
public class DiamondOperatorExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>(); // Type inferred as ArrayList<String>
list.add("Hello");
list.add("World");
list.forEach(System.out::println);
}
}
String in Switch Statement
Feature: Allows using String objects in switch statements.
Example:
public class SwitchStringExample {
public static void main(String[] args) {
String day = "Monday";
switch (day) {
case "Monday":
System.out.println("Start of the week");
break;
case "Friday":
System.out.println("End of the week");
break;
default:
System.out.println("Midweek");
}
}
}
Catch Multiple Exceptions
Feature: Allows catching multiple exceptions in a single catch block.
Example:
public class MultipleCatchExample {
public static void main(String[] args) {
try {
// Some code that may throw IOException or SQLException
} catch (IOException | SQLException e) {
e.printStackTrace();
}
}
}
Automatic Type Inference
Feature: Enhances the type inference capabilities of the Java compiler.
Lambda Expressions
Feature: Allows passing functions as parameters to methods, improving code conciseness.
Example:
import java.util.Arrays;
import java.util.List;
public class LambdaExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name)); // Output: Alice Bob Charlie
}
}
Streams API
Feature: Provides a fluent API for processing sequences of elements.
Example:
import java.util.Arrays;
import java.util.List;
public class StreamsExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println); // Output: Alice
}
}
Optional Class
Feature: Represents optional values to avoid null and NullPointerException.
Example:
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
Optional<String> optionalName = Optional.ofNullable(null);
optionalName.ifPresent(System.out::println); // No output
}
}
New Date and Time API
Feature: Provides a modern and immutable API for date and time.
Example:
import java.time.LocalDate;
public class DateTimeExample {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
System.out.println(today); // Output: current date
}
}
Default Methods
Feature: Allows interfaces to have methods with implementations.
Example:
interface MyInterface {
default void defaultMethod() {
System.out.println("Default method");
}
}
class MyClass implements MyInterface {}
public class DefaultMethodExample {
public static void main(String[] args) {
new MyClass().defaultMethod(); // Output: Default method
}
}
Modules System
Feature: Provides modularization of code and better dependency management.
Example:
// module-info.java
module my.module {
exports com.mycompany.mypackage;
}
JShell
Feature: An interactive REPL tool for testing and experimenting with Java code.
Example:
jshell> System.out.println("Hello, JShell!")
Private Methods in Interfaces
Feature: Allows private methods in interfaces for code reuse within default methods.
Example:
interface MyInterface {
private void privateMethod() {
System.out.println("Private method");
}
default void defaultMethod() {
privateMethod();
}
}
class MyClass implements MyInterface {}
public class PrivateMethodExample {
public static void main(String[] args) {
new MyClass().defaultMethod(); // Output: Private method
}
}
Local-Variable Type Inference (var)
Feature: Enables local variable type inference with var.
Example:
public class LocalVariableInferenceExample {
public static void main(String[] args) {
var message = "Hello, Java 10";
System.out.println(message); // Output: Hello, Java 10
}
}
Application Class-Data Sharing (AppCDS)
Feature: Improves startup time by sharing class metadata across applications.
String Methods
Feature: Adds new methods like isBlank(), lines(), strip(), stripLeading(), stripTrailing().
Example:
public class StringMethodsExample {
public static void main(String[] args) {
String str = " Hello, Java 11! ";
System.out.println(str.strip()); // Output: Hello, Java 11!
}
}
HTTP Client API
Feature: Provides a modern API for making HTTP requests.
Example:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientExample {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.github.com"))
.build();
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
}
}
Removal of Deprecated APIs
Feature: Removes outdated and unused APIs.
Switch Expressions (Preview)
Feature: Enhances the switch statement with a new syntax.
Example:
public class SwitchExpressionExample {
public static void main(String[] args) {
int dayOfWeek = 3; // Wednesday
String dayType = switch (dayOfWeek) {
case 1, 5, 7 -> "Weekend";
case 2, 3, 4 -> "Weekday";
default -> throw new IllegalArgumentException("Invalid day: " + dayOfWeek);
};
System.out.println(dayType); // Output: Weekday
}
}
Shenandoah Garbage Collector (Experimental)
Feature: A low-latency garbage collector.
Text Blocks (Preview)
Feature: Provides multi-line string literals.
Example:
public class TextBlocksExample {
public static void main(String[] args) {
String json = """
{
"name": "John",
"age": 30
}
""";
System.out.println(json);
}
}
Dynamic CDS Archives
Feature: Enhances class-data sharing with dynamic archive creation.
Pattern Matching for instanceof (Preview)
Feature: Simplifies type checking and casting.
Example:
public class InstanceOfExample {
public static void main(String[] args) {
Object obj = "Hello, Java 14!";
if (obj instanceof String s) {
System.out.println(s.toUpperCase()); // Output: HELLO, JAVA 14!
}
}
}
Records (Preview)
Feature: Provides a compact syntax for data classes.
Example:
public record Person(String name, int age) {}
public class RecordExample {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
System.out.println(person.name()); // Output: Alice
}
}
Text Blocks (Standard)
Feature: Finalized the text blocks feature.
Sealed Classes (Preview)
Feature: Allows restricting which classes can extend a class or implement an interface.
Example:
public sealed interface Shape permits Circle, Rectangle {}
public final class Circle implements Shape {}
public final class Rectangle implements Shape {}
public class SealedClassExample {
public static void main(String[] args) {
Shape shape = new Circle();
System.out.println(shape.getClass().getSimpleName()); // Output: Circle
}
}
Hidden Classes
Feature: Support for classes not visible to the application’s class loader.
Records (Standard)
Feature: Finalized the records feature for data classes.
Pattern Matching for instanceof (Standard)
Feature: Finalized pattern matching for instanceof.
JEP 394: Pattern Matching for instanceof
Feature: Finalized the pattern matching feature.
JEP 395: Records
Feature: Finalized the records feature.
Sealed Classes (Standard)
Feature: Finalized the feature for controlling class hierarchies.
New foreign Memory API (Incubator)
Feature: Provides a new API for handling memory outside the Java heap.
Example:
import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.MemorySegments;
public class ForeignMemoryExample {
public static void main(String[] args) {
try (MemorySegment segment = MemorySegment.allocateNative(1024)) {
segment.set(ValueLayout.JAVA_INT, 0, 42);
System.out.println(segment.get(ValueLayout.JAVA_INT, 0)); // Output: 42
}
}
}
Simple Web Server (Incubator)
Feature: Provides a simple HTTP server.
Example:
jdk.httpserver -port 8080
JEP 400: UTF-8 by Default
Feature: Standardizes UTF-8 as the default encoding.
Record Patterns (Preview)
Feature: Enhances pattern matching with record patterns.
Example:
public class RecordPatternsExample {
record Point(int x, int y) {}
public static void main(String[] args) {
Point point = new Point(10, 20);
if (point instanceof Point(var x, var y)) {
System.out.println("x: " + x + ", y: " + y); // Output: x: 10, y: 20
}
}
}
Virtual Threads (Preview)
Feature: Provides a lightweight concurrency model.
Example:
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class VirtualThreadsExample {
public static void main(String[] args) {
try (ExecutorService executor = Executors.newVirtualThreadExecutor()) {
executor.submit(() -> System.out.println("Running in a virtual thread"));
}
}
}
Project Loom (Virtual Threads)
Feature: Enhances concurrency with virtual threads.
Project Panama (Foreign Function & Memory API)
Feature: Finalizes the API for native code and memory.
Project Amber (Pattern Matching and Records Enhancements)
Feature: Enhances pattern matching and records.
Pattern Matching for Switch (Standard)
Feature: Finalizes pattern matching for switch statements.
Example:
public class SwitchPatternExample {
public static void main(String[] args) {
Object obj = "Hello";
String result = switch (obj) {
case String s -> "String of length " + s.length();
case Integer i -> "Integer with value " + i;
default -> "Unknown type";
};
System.out.println(result); // Output: String of length 5
}
}
Foreign Function & Memory API (Standard)
Feature: Finalizes the foreign function and memory API.
Scoped Values (Incubator)
Feature: Provides a new API for managing context data.
Java 8: Introduced functional programming features and modernized the date/time API.
Java 9: Added modularity and interactive tools for experimentation.
Java 10: Simplified local variable declarations and improved startup times.
Java 11: Added new string methods and a modern HTTP client.
Java 12: Enhanced switch statements and introduced a low-latency garbage collector.
Java 13: Standardized text blocks for multi-line strings.
Java 14: Simplified instanceof checks and introduced concise data classes (records).
Java 15: Finalized text blocks and introduced sealed classes.
Java 16: Finalized records and pattern matching for instanceof.
Java 17: Introduced the long-term support release with finalized sealed classes and a new memory API.
Java 18: Added a simple web server and standardized UTF-8 encoding.
Java 19: Enhanced pattern matching and virtual threads.
Java 20: Continued enhancements in concurrency and foreign memory handling.
Java 21: Finalized pattern matching for switch and introduced scoped values.