Modern Java Evolution
Release Cadence & Versions
- Two releases per year (March/September); LTS every 2 years — 21 (2023) and 25 (2025) are current targets
- Preview features need
--enable-previewand can change; incubator APIs likewise - Landmark drops: 8 lambdas/streams; 9 modules; 11 HttpClient + LTS; 17 sealed; 21 virtual threads + pattern matching
- Upgrading LTS→LTS is the mainstream path; each skip accumulates real performance/GC wins for free
- The
--release Nflag compiles against N's API — safer than source/target alone
| Version | Year | Headliners |
|---|---|---|
| 8 | 2014 | lambdas, streams, Optional, java.time |
| 9 | 2017 | modules (JPMS), JShell, six-month cadence begins |
| 11 (LTS) | 2018 | HttpClient, var (10), single-file run, JFR open-sourced |
| 17 (LTS) | 2021 | sealed classes, records (16), pattern matching instanceof, text blocks (15) |
| 21 (LTS) | 2023 | virtual threads, pattern matching for switch, sequenced collections, generational ZGC |
| 25 (LTS) | 2025 | compact source files, scoped values, module import declarations, Shenandoah gen. |
The cadence changed the risk model: instead of a decade-scale big-bang release (Java 9 was five years late), features ship when ready, hardened through preview rounds — pattern matching took four previews across 17–21. For teams this means: read release notes twice a year, adopt on LTS, and treat preview features as experiments, never production commitments (they have changed between previews).
The quiet compounding: each release carries GC improvements (generational ZGC), JIT gains, and startup work that arrive without code changes. Multiple industry benchmarks show double-digit throughput gains going 8 → 17 → 21 purely from the runtime. Staying on 8 (still common) forfeits a decade of free performance — the cheapest optimization most legacy systems have available (Performance Methodology).