Since version 9, Java has new features every 6 months and it’s very hard to keep track of these new changes. Most of the information on the internet describes changes between the last 2 Java versions. However, if you’re in a similar situation as me, you’re not using one of the latest Java versions but a version several releases older.
Then it’s useful to know which new features were added since the version you use now, or between the versions that you use now and the one you want to start using next. Therefore I’ve compiled a table with all new features added since Java 8 for each new Java version and I keep it updated for every newer Java version.
Below you can find tables for:
- New Java language features – additions to the Java language or APIs
- New Java language features in preview/incubation – additions to the Java language or APIs which aren’t in their final state yet
- New tools and features in OpenJDK – additions outside of the language, such as command line tools or JVM improvements
- Deprecated/removed features and APIs
Note that I didn’t include all the new features and API additions, only those that are useful for a wide range of developers, to keep the list brief.
This article isn’t about choosing the right Java version for you to use. But I’ll at least summarize all the Java versions since Java 8 and for your convenience:
- Java 8 – LTS release (Long Term Support), last LTS release before JPMS (modules) were introduced in Java 9
- Java 11 – LTS release
- Java 17 – LTS release, the latest LTS release until September 2023
- Java 19 – non-LTS release, the latest version released in September 2022
- all other Java versions – non-LTS releases
In most cases, you should only use LTS releases in production. That is unless you have specific needs to use the greatest and latest and are willing to upgrade to a new Java version every 6 months. To find out more about Java LTS releases, you can read The art of long-term support and what LTS means for the Java ecosystem by Oracle.
Java language features and APIs
Feature/API | Since | Preview since |
Simple Web Server (a.k.a com.sun.net.httpserver.SimpleFileServer) SimpleFileServer.createFileServer(new InetSocketAddress(9000), path, logLevel).start(); Cmd Line: jwebserver -p 9000 | 18 | |
18 | ||
UTF-8 by Default – instead of the charset defined by the system. Run javac -encoding UTF-8 with JDK 8-17 to check for Java source encoding issues. | 18 | |
Context-Specific Deserialization Filters – allow applications to configure deserialization filters, either specify a pattern via a system property, or a filter factory via a system property or via ObjectInputFilter.Config | 17 | |
Sealed classes (inheritance only for allowed classes): public abstract sealed class Shape permits Circle, Rectangle, Square {...} | 17 | 15 |
Record type – data classes with implicit getters, constructor, equals , hashCode and toString methods:record Point(int x, int y) { } | 16 | 14 |
Static members in inner classes (part of Record type JEP) new Object() { static record MyData(String data) {}; public static final int CONSTANT = 1; }; | 16 | 16 |
16 | 14 | |
15 | 13 | |
New String methods ( formatted, stripIndent, translateEscapes ) | 15 | |
Switch expressions: boolean isWeekend = switch (day) { case SATURDAY, SUNDAY -> true; default -> false ;}; | 14 | 12 |
12 | ||
12 | ||
11 | ||
11 | ||
11 | ||
TLS v1.3 – support for a new SSL/TLS protocol version | 11 | |
10 | ||
9 | ||
9 | ||
9 | ||
9 | ||
9 | ||
9 | ||
this.getClass().getPackageName() | 9 | |
Process API updates (detailed info about processes, e.g. ID, onExit, destroy) | 9 | |
9 | ||
9 | ||
9 | ||
8 | ||
8 | ||
8 | ||
8 | ||
8 | ||
8 | ||
8 | ||
8 | ||
8 |
Java language features or APIs in preview/incubation
Feature/API | Since | Preview since |
Virtual threads Thread.startVirtualThread(runnable) ;Thread.ofVirtual().name("duke").unstarted(runnable); Executors.newVirtualThreadPerTaskExecutor(); Executors.newThreadPerTaskExecutor(threadFactory); | 19 | |
Record patterns record Point(int x, int y) {} | 19 | |
Structured concurrency try (var scope = new ShutdownOnFailure()) { | 19 | |
Pattern Matching for switch – like instanceof for switch ; switch is an expression and can be assignedString result = switch (o) { case 0 -> throw new RuntimeException("Cannot be 0"); // Special cases case Integer i when i > 0 -> "Positive number"; case Integer i -> "Negative number"; // 0 and positive numbers handled by above rules | 17 | |
Foreign Function & Memory API (an alternative to JNI) | 16 | |
Vector API – express computations that compile to optimal hardware instructions | 16 |
New JDK tools and features since OpenJDK 8
Tool / feature | Since | Experimental since |
14 | ||
11 | ||
Experimental Java-Based JIT Compiler (Graal VM) | 10 | |
15 | 12 | |
15 | 11 | |
14 | ||
11 | ||
Flight recorder (data collection framework for troubleshooting) | 11 | |
10, 8u191 | ||
10, 8u191 | ||
10 | ||
jlink – custom JRE image, subset of JRE | 9 | |
JShell (Java REPL) – run Java commands interactively | 9 | |
9 | ||
9 |
Deprecated/removed features and APIs:
Feature / API | Deprecated since | Removed since |
Deprecate Finalization for Removal ( finalize() and similar methods) | 18 | |
17 | ||
Constructors of primitive wrapper classes (e.g. new Integer(1) ) | 16 | |
14 | ||
Applet API (Deprecated For Removal in Java 17) | 9 | |
15 | 17 | |
Strongly Encapsulate JDK Internals (except sun.misc.Unsafe and some more) – internal JDK classes won’t be available anymore | 9 | 17 |
11 | 15 | |
14 | 15 | |
CMS GC | 9 | 14 |
11 | 14 | |
11 | ||
Java Web Start (was only in Oracle JDK) | 9 | 11 |
Java EE and CORBA modules (JAX-WS, JAXB, JAF, Common Annotations, CORBA, JTA) Look here to find replacements for the removed modules | 9 | 11 |
10 | ||
9 | ||
9 | ||
9 | ||
8 | 9 | |
8 | 9 |
For more details, the javaalmanac.io/ catalog is very useful to browse the changes in Java thoughout all its history. It can give you complete diff of APIs between selected Java versions, e.g. between Java 8 and Java 11. Very useful If you’re thinking about migrating to a specific Java version.
Dávid Csákvári also wrote a similar article as mine for new features between Java 8 and Java 17, which is more detailed and with a lot of useful examples.
If you want to get started with Java 17 quickly and try out all the new features, here’s a nice article to follow to get you started fast: Java 17 New Features Tutorial.
Thank you so much for this post!
This doesn’t include the `formatted` method in strings introduced in Java 15
Thank you for the hint, Mateo. I’ve added info about String.formatted and the other 2 methods added in Java 15. Although just brief into, I want this article to highlight the major changes so that people know what might be interesting to look at and start using when they upgrade.
Alright, cool! Yeah it’s just I think that formatted is a rather significant change; it’s changed how I inject variables into strings (it’s more syntactically nice this way imo)
Sure, that’s why I added it 🙂 Thanks again!
No problem 🙂
Really appreciated, indeed
Hi Ondro,
I just read, that since JEP 395, inner classes do now allow for static members which was previously a compile time error. Since nested classes are an important feature, I think it might be worth enlisting this change here.
BTW: Thank you so much, for this great aggregation of changes! I wonder why a big company like Oracle, who actually owns the language!, has not done it.
Great suggestion, Mathias, thanks! I’ve added it to the list. I didn’t realize it as it was hidden in the Records JEP but doesn’t apply only to records.
Hi Ondra, great article. I know it’s a little bit out of scope but could you please include changes in licensing policies?
Thank you for this summary!
Awesome. Pure gold!
I searched this for long time, thank you!