跪拜 Guibai
← Back to the summary

Java's Four-Generation Leap: From Lambdas to Virtual Threads

JDK 8 → 17 → 21 → 25: A Clear Explanation of the Key Leaps Across Four Generations

1. Version Positioning and Release Strategy

First, let's clarify the positioning of the four versions:

The change in release cadence is key to understanding the Java ecosystem:

This strategic change directly impacts our technology choices. Many teams stayed on JDK 8 for nearly a decade, the core reason being that there was no LTS version between JDK 9 and JDK 16 worth the risk of upgrading. JDK 17 was the first version that truly made everyone feel "it's time to upgrade."

A couple of words on licensing: After JDK 8u211, commercial use of Oracle JDK requires a fee. Starting with JDK 17, Oracle reinstated the NFTC (No-Fee Terms and Conditions) license, allowing free commercial use. However, many companies have already switched to distributions like Adoptium (Eclipse Temurin), Amazon Corretto, and Azul Zulu, which are free across all versions.

2. Language Feature Evolution

2.1 JDK 8: The Functional Revolution of Lambda and Stream

JDK 8 is the most significant language-level change in Java's history. It introduced four core features—Lambda, Stream, Optional, and the new Date API—all at once, directly changing Java's programming paradigm.

Lambda Expressions and Functional Interfaces

Writing a thread sort before JDK 8:

After JDK 8:

Lambda's underlying implementation is worth understanding: it is not syntactic sugar for anonymous inner classes. The compiler uses the invokedynamic instruction to generate implementation classes at runtime via LambdaMetafactory, avoiding the problem of anonymous inner classes generating a large number of .class files at compile time. You can see this difference using javap -c -p:

Stream API

The core design of Stream is lazy evaluation. Intermediate operations (filter, map, flatMap) are not executed immediately; the entire pipeline is processed only when a terminal operation (collect, forEach, reduce) is triggered:

Regarding parallel streams, my advice is: rarely use them in web applications. Parallel streams use ForkJoinPool.commonPool() under the hood, which is a globally shared thread pool. If you use a parallel stream for a time-consuming operation within one HTTP request handler, it will affect the execution of parallel streams in other requests. We once encountered interface timeouts in production because of this.

The diagram above shows the complete processing flow of a Stream pipeline—from the data source to intermediate operations (lazy) to terminal operations (triggering execution), as well as the Fork-Join divide-and-conquer model of parallel streams.

Optional

java.time API

Finally replaced the disastrous java.util.Date and Calendar:

2.2 Key Transitional Features of JDK 9-16

Many people skip this section entirely, but the transitional features of JDK 9-16 were all finalized in subsequent LTS versions. Without understanding their evolution, you'll feel these features "appeared out of nowhere" when using JDK 17/21.

JDK 9: Module System (Project Jigsaw)

JDK 9 also introduced collection factory methods, JShell, and private interface methods:

JDK 10: Local-Variable Type Inference (var)

JDK 11: String Enhancements, HttpClient Standardization

JDK 14: Records (Preview), Pattern Matching for instanceof (Preview)

JDK 15: Text Blocks

2.3 JDK 17: The Maturation of Language Features

JDK 17 finalized all the features that were in preview during JDK 14-16, forming a complete "Modern Java" feature set.

Sealed Classes (JEP 409)

Sealed classes restrict the range of subclasses for a class. When used with pattern matching, the compiler can perform exhaustiveness checks:

The diagram shows the inheritance constraints of Sealed Classes—a sealed interface only allows specified subclasses to implement it, a final subclass cannot be extended further, and a non-sealed subclass opens up extension.

Pattern Matching for instanceof (JEP 394)

Other notable changes in JDK 17:

2.4 The Transition of JDK 18-20

These three non-LTS versions laid the groundwork for two killer features in JDK 21:

2.5 JDK 21: A Revolution in the Concurrency Model

JDK 21 is the most significant change to the Java platform since JDK 8. The official release of Virtual Threads fundamentally changes Java's concurrent programming model.

Virtual Threads (JEP 444)

A Virtual Thread cannot simply be described as a "lightweight thread." Its essence is turning threads from an operating system resource into a JVM-managed resource.

Problems with traditional Platform Threads:

Implementation mechanism of Virtual Threads: