java-evolution is a practical Java reference project that demonstrates or documents features introduced in each Java release from Java 1 through Java 26.
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+
- GNU Make, if you want to use the documented
maketargets - Node.js, if you want to run
make docs-audit,make docs-check, ormake release-checklocally lychee, if you want to runmake docs-checkormake release-checklocally
This repository uses the local Maven installation on your machine. It does not use the Maven wrapper.
The project has been validated on macOS, Windows 11, and Linux. The examples are plain Java, and the helper scripts under scripts/ provide platform-specific ways to switch the current terminal session to JDK 25 before running Maven.
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 Linux:
source scripts/use-java-25-linux.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 Linux helper looks for JDK 25 in JAVA25_HOME, JDK25_HOME, /usr/lib/jvm, /opt, /usr/local, and SDKMAN candidate directories. If your JDK is somewhere else, pass it explicitly:
source scripts/use-java-25-linux.sh /usr/lib/jvm/jdk-25.0.2The 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 run only the focused practical demo tests:
make demosTo print the active Java/Maven versions and run the test suite:
make checkTo run the final local pre-release gate:
make release-checkTo check documentation navigation consistency:
make docs-auditTo run the full documentation validation gate:
make docs-checkTo 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 or explanatory modules 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 or explanatory modules because they are not a good fit for a tiny portable JUnit example.- Documentation health is checked locally with
make docs-check; navigation and links are also checked in GitHub Actions. - JavaDoc is generated locally with
make docsand published through GitHub Pages. - GitHub Actions use the same Make targets where practical, so local commands and CI stay aligned.
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, java01 refreshes early Java foundations, java05 demonstrates Java 5 features, and 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 or explanatory module, the status tables use labels such as final, notes-only or final, explanatory module: final describes the Java feature, and the second label describes how this repository documents it.
src/main/java/net/jrodolfo/java_evolution/
java01/
java02/
java03/
java04/
java05/
java06/
java07/
java08/
java09/
java10/
...
java26/
src/test/java/net/jrodolfo/java_evolution/
java01/
java02/
java03/
java04/
java05/
java06/
java07/
java08/
java09/
java10/
...
java26/
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.
-
Wanting the historical dates: use the Java Release Timeline.
-
Looking for hands-on walkthroughs: use the Practical Demos.
-
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: repository release history.
-
Study Guide: suggested learning path through Java 1-26.
-
Java Release Timeline: release months and historical naming context from Java 1 through Java 26.
-
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.
-
Practical Demos: focused walkthroughs for tooling, security, native, and class-file features, with
make demosas a pre-demo check. -
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.5.1 Release Notes: latest GitHub release text; older release notes live in
docs/release/. -
JavaDoc Site: generated API documentation published by GitHub Pages.
| Java | Released | Package | Highlights |
|---|---|---|---|
| 1 | Jan 1996 / Feb 1997 | java01 |
Object-Oriented Foundations, Interfaces, Checked Exceptions, Threads, java.io, Inner Classes, Reflection, Serialization, JDBC, RMI, and JavaBeans examples |
| 2 | Dec 1998 | java02 |
Collections Framework, Sorting, strictfp, Swing, Java 2D, and Security Policy examples |
| 3 | May 2000 | java03 |
Dynamic Proxy, Timer, Shutdown Hooks and JNDI examples, Legacy Integration notes |
| 4 | Feb 2002 | java04 |
Assertions, Regex, NIO, Logging, Chained Exceptions, XML, and Security examples, Preferences notes |
| 5 | Sep 2004 | java05 |
Generics, Enhanced For Loop, Autoboxing, Enums, Varargs, Static Import, Annotations, Concurrency Utilities |
| 6 | Dec 2006 | java06 |
Navigable Collections, Monitoring/MXBeans example, Scripting/Compiler/Console/Web-Service explanatory modules |
| 7 | Jul 2011 | java07 |
Try-With-Resources, Multi-Catch, Diamond Operator, String Switch, NIO.2, Fork/Join, invokedynamic example |
| 8 | Mar 2014 | java08 |
Lambdas, Streams, Optional, Method References, CompletableFuture, Default Methods, Date/Time API |
| 9 | Sep 2017 | java09 |
Collection Factories, Optional/Stream Enhancements, Private Interface Methods, Process API, StackWalker, Module System example |
| 10 | Mar 2018 | java10 |
var, Unmodifiable Collectors, Optional.orElseThrow() |
| 11 | Sep 2018 | java11 |
String APIs, Files read/write string, HTTP Client, Predicate.not, lambda var, Optional.isEmpty |
| 12 | Mar 2019 | java12 |
Switch Expressions preview, Collectors.teeing, String.indent, Files.mismatch, Compact Number Format |
| 13 | Sep 2019 | java13 |
Text Blocks preview, switch yield preview, FileSystems.newFileSystem(Path) |
| 14 | Mar 2020 | java14 |
Switch Expressions final, Helpful NullPointerExceptions, Records preview, Pattern Matching for instanceof preview |
| 15 | Sep 2020 | java15 |
Text Blocks final, Sealed Classes preview, Hidden Classes example |
| 16 | Mar 2021 | java16 |
Records final, Pattern Matching for instanceof final, Stream.toList, Unix-domain socket example |
| 17 | Sep 2021 | java17 |
Sealed Classes final, Pattern Matching for switch preview, Random Generator API, HexFormat, Strong Encapsulation example |
| 18 | Mar 2022 | java18 |
UTF-8 default charset, Simple Web Server example, JavaDoc snippets example, Internet-Address Resolution SPI example |
| 19 | Sep 2022 | java19 |
Virtual Threads preview, Record Patterns preview, Pattern Matching switch preview, Structured Concurrency notes, FFM notes |
| 20 | Mar 2023 | java20 |
Record Patterns second preview, Pattern Matching switch fourth preview, Vector API example, Scoped Values/Structured Concurrency/FFM notes |
| 21 | Sep 2023 | java21 |
Virtual Threads final, Record Patterns final, Pattern Matching for switch final, Sequenced Collections, KEM example |
| 22 | Mar 2024 | java22 |
Unnamed Variables and Patterns final, FFM executable native example, Stream Gatherers explanatory module, Class-File API explanatory module |
| 23 | Sep 2024 | java23 |
Markdown Documentation Comments, Unsafe Memory-Access, and ZGC examples, preview notes |
| 24 | Mar 2025 | java24 |
Stream Gatherers final, Class-File API, Security Manager/AOT/runtime modules, post-quantum crypto examples, preview bridge modules |
| 25 | Sep 2025 | java25 |
Scoped Values final, Flexible Constructor Bodies final, Module Imports, KDF, Compact Source Files, JFR, AOT, and Object Headers examples, GC notes |
| 26 | Mar 2026 | java26 |
HTTP/3 notes, Final Field restrictions, Applet API removal, AOT Object Caching, G1, PEM/Structured Concurrency/Lazy Constants/Vector/Primitive Patterns 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.
Java 1 through Java 7 predate the modern OpenJDK release-project pages and the JEP process used for later releases. Their historical release notes, specifications, and API references are tracked in docs/jep-index.md and in the individual version READMEs.
- 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
- OpenJDK JDK 26
- Software Developer: Rod Oliveira
- GitHub: https://github.com/jrodolfo
- Webpage: https://jrodolfo.net
- MIT License
- Copyright (c) 2026 Rod Oliveira
- See LICENSE