java-evolution is a practical Java reference project that demonstrates features introduced in each Java release from Java 8 through Java 25.
I built this repository as a place to learn, test, and document how Java has evolved over time. It is primarily for my own continued growth, but it is also meant to help other developers who want concise examples of newer language features, APIs, and idioms.
The project is intentionally lightweight. Spring Boot provides the project shell and Maven setup, but the examples are plain Java classes with focused JUnit tests. The main goal is to make each feature easy to read, run, and revisit during study or interview preparation.
Java keeps evolving, and day-to-day work can easily settle into older habits. This repository makes that evolution concrete through code: what changed, why it matters, and how newer Java can be used clearly and effectively.
The emphasis is clarity over cleverness. Examples should stay small, readable, and easy to run. When useful, they should show not only how a feature works, but also what problem it solves.
- JDK 25
- Maven 3.9+
This repository uses the local Maven installation on your machine. It does not use the Maven wrapper.
If you usually keep another JDK on your machine, use one of these helpers to switch the current terminal session to JDK 25 before running Maven.
On macOS:
source scripts/use-java-25-mac.shOn Windows with Git Bash:
source scripts/use-java-25-windows.shOn Windows with PowerShell:
.\scripts\use-java-25-windows.ps1If PowerShell blocks local scripts on a fresh Windows install, allow scripts only for the current terminal session and then run the helper:
Set-ExecutionPolicy -Scope Process Bypass
.\scripts\use-java-25-windows.ps1The Windows helpers look for JDK 25 in JAVA25_HOME, JDK25_HOME, C:\dev\apps, and common Program Files Java install directories. If your JDK is somewhere else, pass it explicitly:
source scripts/use-java-25-windows.sh /c/dev/apps/jdk-25.0.0.\scripts\use-java-25-windows.ps1 -JavaHome C:\dev\apps\jdk-25.0.0After switching Java, confirm Maven is also using JDK 25:
mvn --versionThen run the test suite:
make testTo print the active Java/Maven versions and run the test suite:
make checkTo check documentation navigation consistency:
make docs-auditTo generate the local JavaDoc reference:
make docsThe generated JavaDoc is written to target/site/apidocs/index.html.
The published JavaDoc site is available at https://jrodolfo.github.io/java-evolution/.
- Examples are built and tested against the required JDK listed above.
- Spring Boot is used as lightweight project tooling; the examples themselves are plain Java.
- Some features are represented by
Notesclasses because they involve preview flags, incubator modules, native code, JVM flags, external tools, cryptography providers, source-launcher behavior, or runtime behavior. Notesdoes not mean a Java feature is unfinished. Some final features are documented as notes because they are not a good fit for a tiny portable JUnit example.- Documentation navigation is checked locally with
make docs-auditand in GitHub Actions. - JavaDoc is generated locally with
make docsand published through GitHub Pages.
The Maven build uses a single Java release for every package:
<java.version>25</java.version>Each package demonstrates features introduced in a specific Java release. For example, java08 demonstrates Java 8 features, while java21 demonstrates Java 21 features.
Some older preview or incubator features changed before becoming final. In those cases, the project either:
- uses syntax compatible with the configured project JDK and explains the original preview status, or
- uses a
Notesclass when the original feature requires preview flags, incubator modules, native code, JVM flags, external processes, or platform-specific setup.
When a feature is final but represented by a notes class, the status tables say final, notes-only: final describes the Java feature, and notes-only describes how this repository documents it.
src/main/java/net/jrodolfo/java_evolution/
java08/
java09/
java10/
...
java25/
src/test/java/net/jrodolfo/java_evolution/
java08/
java09/
java10/
...
java25/
Example classes contain JavaDoc. Test classes are written as executable documentation with clear assertions. Packages can also include a version README with a deeper explanation of the problems each feature solved.
Start here depending on what you need:
-
New to the repository: read this README, then follow the Study Guide.
-
Moving from an older Java baseline: use the Migration Guide.
-
Studying over multiple sessions: use the Learning Path.
-
Looking up acronyms and recurring platform terms: use the Glossary.
-
Looking for one feature quickly: use the Feature Map.
-
Checking maturity or official references: use the Status Matrix and JEP Index.
-
Preparing to present the project: use the Interview Guide and Demo Script.
-
Preparing a release: use the Release Checklist.
-
Browsing API-style documentation: use the JavaDoc Site.
-
Changelog: release history.
-
Study Guide: suggested learning path through Java 8-25.
-
Migration Guide: practical guide for moving from Java 8, 11, 17, or 21 to newer baselines.
-
Learning Path: staged study sessions with files to read, tests to run, and interview angles.
-
Glossary: acronyms and recurring Java platform terms used throughout the repository.
-
Interview Guide: talking points and demo flow for interviews.
-
Demo Script: practical 5-10 minute live walkthrough.
-
JEP Index: centralized JEP links with status labels.
-
Feature Map: class-by-class navigation table.
-
Status Matrix: feature status, example class, test class, and reference links.
-
Release Checklist: repeatable release process.
-
v1.0.0 Release Notes: draft text for the first GitHub release.
-
JavaDoc Site: generated API documentation published by GitHub Pages.
| Java | Package | Highlights |
|---|---|---|
| 8 | java08 |
Lambdas, Streams, Optional, Method References, CompletableFuture, Default Methods, Date/Time API |
| 9 | java09 |
Collection Factories, Optional/Stream Enhancements, Private Interface Methods, Process API, StackWalker, Modules notes |
| 10 | java10 |
var, Unmodifiable Collectors, Optional.orElseThrow() |
| 11 | java11 |
String APIs, Files read/write string, HTTP Client, Predicate.not, lambda var, Optional.isEmpty |
| 12 | java12 |
Switch Expressions preview, Collectors.teeing, String.indent, Files.mismatch, Compact Number Format |
| 13 | java13 |
Text Blocks preview, switch yield preview, FileSystems.newFileSystem(Path) |
| 14 | java14 |
Switch Expressions final, Helpful NullPointerExceptions, Records preview, Pattern Matching for instanceof preview |
| 15 | java15 |
Text Blocks final, Sealed Classes preview, Hidden Classes notes |
| 16 | java16 |
Records final, Pattern Matching for instanceof final, Stream.toList, Unix-domain socket notes |
| 17 | java17 |
Sealed Classes final, Pattern Matching for switch preview, Random Generator API, HexFormat, Strong Encapsulation notes |
| 18 | java18 |
UTF-8 default charset, Simple Web Server notes, JavaDoc snippets notes, InetAddress resolver SPI notes |
| 19 | java19 |
Virtual Threads preview, Record Patterns preview, Pattern Matching switch preview, Structured Concurrency notes, FFM notes |
| 20 | java20 |
Record Patterns second preview, Pattern Matching switch fourth preview, Scoped Values/Structured Concurrency/FFM/Vector notes |
| 21 | java21 |
Virtual Threads final, Record Patterns final, Pattern Matching for switch final, Sequenced Collections, KEM notes |
| 22 | java22 |
Unnamed Variables and Patterns final, FFM final documented via notes, Stream Gatherers preview notes, Class-File API preview notes |
| 23 | java23 |
Markdown Documentation Comments, Primitive Patterns preview notes, Module Imports preview notes, ZGC Generational Mode notes |
| 24 | java24 |
Stream Gatherers final, Class-File API notes, Security Manager disabled, Virtual Thread synchronization notes, post-quantum crypto notes |
| 25 | java25 |
Scoped Values final, Flexible Constructor Bodies final, Module Imports and Compact Source Files final documented via notes, KDF/JFR/AOT/GC notes |
Start with the package for the Java version you want to review. Read the example class first, then read the matching test.
For example:
src/main/java/net/jrodolfo/java_evolution/java08/StreamExamples.java
src/test/java/net/jrodolfo/java_evolution/java08/StreamExamplesTest.java
The tests are meant to explain the expected behavior. Running make test proves that the examples compile and behave as documented. Running make docs generates a browsable JavaDoc reference for the example classes.
Tests are the executable examples. To focus on one topic, run only the matching test class:
mvn -Dtest=StreamExamplesTest test
mvn -Dtest=VirtualThreadsExamplesTest test
mvn -Dtest=ScopedValuesExamplesTest testUse the class names in docs/feature-map.md to choose a specific example.
- OpenJDK JDK 8
- OpenJDK JDK 9
- OpenJDK JDK 10
- OpenJDK JDK 11
- OpenJDK JDK 12
- OpenJDK JDK 13
- OpenJDK JDK 14
- OpenJDK JDK 15
- OpenJDK JDK 16
- OpenJDK JDK 17
- OpenJDK JDK 18
- OpenJDK JDK 19
- OpenJDK JDK 20
- OpenJDK JDK 21
- OpenJDK JDK 22
- OpenJDK JDK 23
- OpenJDK JDK 24
- OpenJDK JDK 25
- Software Developer: Rod Oliveira
- GitHub: https://github.com/jrodolfo
- Webpage: https://jrodolfo.net
- MIT License
- Copyright (c) 2026 Rod Oliveira
- See LICENSE