Skip to content

Java Version Features (8 through 21)

DodaTech Updated 2026-06-28 7 min read

In this tutorial, you will learn about Java Version Features (8 through 21). We cover key concepts, practical examples, and best practices to help you master this topic.

Java's Rapid Release Cadence

Since Java 9, Oracle adopted a six-month release cycle, delivering new features faster and more predictably. This changed Java from a language that stagnated between major releases (Java 6 to 7 took 5 years, 7 to 8 took 4 years) to one that evolves continuously. Understanding which version introduced which feature helps you leverage modern Java capabilities while maintaining compatibility with your target runtime.

This lesson surveys the most impactful language and API features from Java 8, the watershed release that transformed Java, through Java 21, the latest LTS release as of 2026.

timeline
    title Java Version Timeline
    2014 : Java 8 : Lambdas, Streams, Optional
    2017 : Java 9 : Modules, JShell, HttpClient
    2018 : Java 10 : var (LVTI)
    2018 : Java 11 : LTS, HttpClient GA, Nest-Based Access
    2019 : Java 12-13 : Switch Expressions (Preview)
    2020 : Java 14-15 : Records, Text Blocks, Sealed Classes (Preview)
    2021 : Java 17 : LTS, Sealed Classes GA, Pattern Matching
    2023 : Java 21 : LTS, Virtual Threads, Record Patterns

Java 8 (March 2014)

Java 8 was a landmark release that introduced functional programming concepts to Java.

Lambda Expressions

// Before Java 8: anonymous inner class
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Clicked");
    }
});

// Java 8: lambda expression
button.addActionListener(e -> System.out.println("Clicked"));

Stream API

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
    .filter(name -> name.startsWith("A"))
    .map(String::toUpperCase)
    .forEach(System.out::println); // ALICE

Optional

Optional<String> maybeName = Optional.ofNullable(getName());
String name = maybeName.orElse("Default");

Default and Static Methods in Interfaces

interface Vehicle {
    void drive();
    
    default void honk() {
        System.out.println("Beep!");
    }
    
    static boolean isLegal() {
        return true;
    }
}

Java 9 (September 2017)

JPMS (Java Platform Module System)

Already covered in lesson 58. The module system was the headline feature.

JShell (REPL)

jshell> System.out.println("Hello, JShell!")
Hello, JShell!

Collection Factory Methods

List<String> list = List.of("a", "b", "c");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> map = Map.of("key1", 1, "key2", 2);

Private Interface Methods

interface Logger {
    default void log(String msg) {
        log(msg, Level.INFO);
    }
    
    private void log(String msg, Level level) {
        // Shared implementation
    }
}

Java 10 (March 2018)

Local Variable Type Inference (var)

var list = new ArrayList<String>();          // infers ArrayList<String>
var stream = list.stream().filter(s -> !s.isEmpty());
var pair = Map.entry("key", "value");

var works only for local variables with initializers. It does not work for fields, method parameters, or return types.

Java 11 (September 2018, LTS)

HttpClient Standardization

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com"))
    .GET()
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());

Running Single-File Source Code

java HelloWorld.java

No compilation step needed for simple programs.

Nest-Based Access

Classes inside the same nest (typically a class and its inner classes) can access each other's private members without synthetic accessor methods.

class Outer {
    private int x = 10;
    
    class Inner {
        void show() {
            System.out.println(x); // No synthetic accessor needed in Java 11+
        }
    }
}

Java 14-15 (March/September 2020)

Records (Java 14 preview, 16 stable)

record Point(int x, int y) { }

var p = new Point(3, 4);
System.out.println(p.x());      // 3
System.out.println(p);          // Point[x=3, y=4]

Text Blocks (Java 13 preview, 15 stable)

String json = """
    {
        "name": "Alice",
        "age": 30,
        "city": "New York"
    }
    """;

Pattern Matching for instanceof (Java 14 preview, 16 stable)

if (obj instanceof String s) {
    System.out.println(s.length());
}

Java 17 (September 2021, LTS)

Sealed Classes

sealed interface Shape permits Circle, Rectangle, Triangle { }

final class Circle implements Shape { }
final class Rectangle implements Shape { }
final class Triangle implements Shape { }

Pattern Matching for switch (Preview)

String formatted = switch (obj) {
    case Integer i -> "int: " + i;
    case String s -> "str: " + s;
    case null -> "null";
    default -> "unknown";
};

Strong Encapsulation of JDK Internals

Reflection access to internal APIs is restricted by default. Use --add-opens to open specific packages.

Java 21 (September 2023, LTS)

Virtual Threads (Project Loom)

Covered in detail in lesson 57.

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> System.out.println("Hello from VT"));
}

Record Patterns

record Address(String city, String zip) { }

if (obj instanceof Person(var name, var age, Address(var city, var zip))) {
    System.out.println(name + " lives in " + city);
}

Pattern Matching for switch (Stable)

String result = switch (value) {
    case null -> "null";
    case String s when s.length() > 10 -> "long string";
    case String s -> "short string";
    case Integer i -> "number: " + i;
    case int[] arr -> "array of length " + arr.length;
    default -> "other";
};

Sequenced Collections

interface SequencedCollection<E> extends Collection<E> {
    SequencedCollection<E> reversed();
    void addFirst(E e);
    void addLast(E e);
    E getFirst();
    E getLast();
    E removeFirst();
    E removeLast();
}

String Templates (Preview)

String name = "Alice";
String message = STR."Hello, \{name}!";

Feature Comparison Table

Feature Java Version Status
Lambda Expressions 8 Stable
Stream API 8 Stable
Optional 8 Stable
JPMS (Modules) 9 Stable
var (LVTI) 10 Stable
HttpClient 11 Stable
Records 16 Stable
Pattern Matching (instanceof) 16 Stable
Sealed Classes 17 Stable
Virtual Threads 21 Stable
Pattern Matching (switch) 21 Stable
Record Patterns 21 Stable
Sequenced Collections 21 Stable
String Templates 21+ Preview
Scoped Values 21+ Preview

Common Mistakes

1. Assuming Everyone Uses the Latest Java

Many enterprises are still on Java 11 or Java 17. Check your target runtime before using Java 21 features like virtual threads.

2. Overusing var

var can harm readability when the type is not obvious from the initializer.

var result = complexMethodCall(); // What type is result?

3. Forgetting That Records Are Immutable

Records are shallowly immutable. If a record component is a mutable object (like ArrayList), the record does not protect it.

4. Ignoring API Deprecation

APIs like finalize(), SecurityManager, and Thread.stop() have been deprecated for removal. Use their replacements.

5. Using Preview Features in Production

Preview features may change in future releases. Do not rely on preview features for production code unless you are willing to track changes.

6. Not Updating build.gradle or pom.xml

New features often require specific compiler versions and language level settings.

<!-- Maven: Java 21 -->
<properties>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
</properties>

Practice Questions

  1. What is the difference between a preview feature and a stable feature?
  2. How does Java 21's SequencedCollection improve upon standard Collection?
  3. Why was public static void main changed in Java 21 to allow void main() without parameters?
  4. What are the advantages of HttpClient over the legacy URLConnection?
  5. How does pattern matching for switch improve code readability compared to traditional if-else chains?

Challenge: Rewrite a legacy Java 8 codebase that uses anonymous inner classes, manual null checks, and StringBuilder, to use Java 21 features including lambdas, Optional, text blocks, records, and pattern matching.

FAQ

Should I upgrade to every new Java release?

For production, use LTS releases (8, 11, 17, 21). Non-LTS releases are suitable for development and testing but have shorter support windows.

Can I use Java 21 features while targeting Java 11?

No. Features like records, sealed classes, and virtual threads require matching runtime support. The --release flag restricts language features to the specified version.

What happened to Java EE?

Java EE was donated to the Eclipse Foundation and rebranded as Jakarta EE. The javax.* namespace changed to jakarta.* starting with Jakarta EE 9.

Why is Java 8 still widely used?

Legacy applications, library compatibility concerns, and slow enterprise adoption cycles keep many organizations on Java 8. However, security risks of unsupported versions make upgrading critical.

What is the difference between Java SE, Jakarta EE, and Java ME?

Java SE is the standard edition for desktop and server applications. Jakarta EE (formerly Java EE) adds enterprise features like servlets and JPA. Java ME targets embedded devices.

Mini Project: Java Version Migration Tool

Create a utility that scans a source directory and identifies code patterns that can be modernized. For each file, report:

  • Anonymous inner classes that can become lambdas
  • Traditional for loops that can become stream operations
  • Classes that can become records
  • String concatenation that can become text blocks
  • Null checks that can become Optional
  • instanceof checks that can use pattern matching

Output a migration report as formatted text.

What's Next

Now that you have a broad view of Java's evolution, the next module explores enterprise Java. You will start with JDBC and Database Connectivity to learn how Java applications interact with relational databases.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro