Java versions
Current preview features
JEP 447: Statements before super(…) (Preview)
-
Preview: 22
public Sub(Certificate certificate) {
var publicKey = certificate.getPublicKey();
if (publicKey == null)
throw new IllegalArgumentException("null certificate");
final byte[] byteArray = switch (publicKey) {
case RSAKey rsaKey -> ...
case DSAPublicKey dsaKey -> ...
...
default -> ...
};
super(byteArray);
}
JEP 463: Implicitly Declared Classes and Instance Main Methods (Second Preview)
-
Preview: 21
Evolve the Java programming language so that students can write their first programs without needing to understand language features designed for large programs.
void main() {
System.out.println("Hello World!");
}
Java 22
March 2024
JEP 456: Unnamed Variables & Patterns
Java programming language is enhanced with unnamed variables and unnamed patterns, which can be used when variable declarations or nested patterns are required but never used. Both are denoted by the underscore character, _.
try (var _ = ScopedContext.acquire()) { // Unnamed variable
... no use of acquired resource ...
} catch (Exception _) { ... }
...stream.collect(Collectors.toMap(
String::toUpperCase,
_ -> "NODATA")) // Unnamed variable
JEP 458: Launch Multi-File Source-Code Programs
Enhance the java application launcher to be able to run a program supplied as multiple files of Java source code. This will make the transition from small programs to larger ones more gradual, enabling developers to choose whether and when to go to the trouble of configuring a build tool.
// file MainApplication.java
public class MainApplication {
public static void main(String[] args) {
Person p = new Person("Billy", "Korando");
System.out.println("Hello, " + p.toString() + "!");
}
}
// file Person.java
record Person(String fName, String lName) {
public String toString(){
return fName + " " + lName;
}
}
$ java MainApplication.java
Hello Billy Korando!
Java 21
JEP 431: Sequenced Collections
It introduces new interfaces to represent collections with a defined encounter order.
SequencedCollection:
interface SequencedCollection<E> extends Collection<E> {
// new method
SequencedCollection<E> reversed();
// methods promoted from Deque
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}
SequencedSet:
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> { SequencedSet<E> reversed(); // covariant override }
SequencedMap:
interface SequencedMap<K,V> extends Map<K,V> {
// new methods
SequencedMap<K,V> reversed();
SequencedSet<K> sequencedKeySet();
SequencedCollection<V> sequencedValues();
SequencedSet<Entry<K,V>> sequencedEntrySet();
V putFirst(K, V);
V putLast(K, V);
// methods promoted from NavigableMap
Entry<K, V> firstEntry();
Entry<K, V> lastEntry();
Entry<K, V> pollFirstEntry();
Entry<K, V> pollLastEntry();
}
JEP 441: Pattern Matching for switch
-
Preview: 17
Java programming language is enhanced with pattern matching for switch expressions and statements.
Improved enum constant case labels:
sealed interface Currency permits Coin {}
enum Coin implements Currency { HEADS, TAILS }
static void goodEnumSwitch1(Currency c) {
switch (c) {
case Coin.HEADS -> { // Qualified name of enum constant as a label
System.out.println("Heads");
}
case Coin.TAILS -> {
System.out.println("Tails");
}
}
}
static void goodEnumSwitch2(Coin c) {
switch (c) {
case HEADS -> {
System.out.println("Heads");
}
case Coin.TAILS -> { // Unnecessary qualification but allowed
System.out.println("Tails");
}
}
}
Patterns in switch labels:
static void patternSwitchTest(Object obj) {
String formatted = switch (obj) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};
}
static void testNew(Object obj) {
switch (obj) {
case String s when s.length() == 1 -> ...
case String s -> ...
...
}
}
Enhanced type checking:
record Point(int i, int j) {}
enum Color { RED, GREEN, BLUE; }
static void typeTester(Object obj) {
switch (obj) {
case null -> System.out.println("null");
// Beware of dominance of String over CharSequence!
case CharSequence cs -> System.out.println("CharSequence");
case String s -> System.out.println("String");
case Color c -> System.out.println("Color: " + c.toString());
case Point p -> System.out.println("Record class: " + p.toString());
case int[] ia -> System.out.println("Array of ints of length" + ia.length);
default -> System.out.println("Something else");
}
}
JEP 440: Record Patterns
-
Preview: 19
Java programming language is enhanced with record patterns to deconstruct record values.
Pattern matching and records:
static void printSum(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x+y);
}
}
Nested record patterns:
static void printColorOfUpperLeftPoint(Rectangle r) {
if (r instanceof Rectangle(ColoredPoint(Point p, Color c),
ColoredPoint lr)) {
System.out.println(c);
}
}
static void printXCoordOfUpperLeftPointWithPatterns(Rectangle r) {
if (r instanceof Rectangle(ColoredPoint(Point(var x, var y), var c),
var lr)) {
System.out.println("Upper-left corner: " + x);
}
}
JEP 444: Virtual Threads
-
Preview: 19
It introduces virtual threads to the Java Platform. Virtual threads are lightweight threads that dramatically reduce the effort of writing, maintaining, and observing high-throughput concurrent applications.
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
} // executor.close() is called implicitly, and waits
Java 18
March 2022
JEP 413: Code Snippets in Java API Documentation
It introduces an @snippet
tag for JavaDoc’s Standard Doclet, to simplify the inclusion of example source code in API documentation.
Markup tags define regions within the content of a snippet: @start
, @end
, @highlight
, @replace
, and @link
.
Inline snippets: An inline snippet contains the content of the snippet within the tag itself.
/**
* The following code shows how to use {@code Optional.isPresent}:
* {@snippet :
* if (v.isPresent()) {
* System.out.println("v: " + v.get());
* }
* }
*/
External snippets: An external snippet refers to a separate file that contains the content of the snippet.
/**
* The following code shows how to use {@code Optional.isPresent}:
* {@snippet file="ShowOptional.java" region="example"}
*/
public class ShowOptional {
void show(Optional<String> v) {
// @start region="example"
if (v.isPresent()) {
System.out.println("v: " + v.get());
}
// @end
}
}
JEP 400: UTF-8 by Default
UTF-8 is specified as the default charset of the standard Java APIs.
Java 17 LTS
September 2021
JEP 409: Sealed Classes
-
Release: 17
-
Preview: 15
Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them.
Exactly one of the modifiers final
, sealed
, and non-sealed
must be used by each permitted subclass.
sealed interface Celestial
permits Planet, Star, Comet { ... }
final class Planet implements Celestial { ... }
final class Star implements Celestial { ... }
final class Comet implements Celestial { ... }
Java 16
March 2021
JEP 395: Records
-
Release: 16
Java introduced records, classes that act as transparent carriers for immutable data.
record Range(int lo, int hi) {
// Compact canonical validating constructor
Range {
if (lo > hi) // referring here to the implicit constructor .parameters
throw new IllegalArgumentException(String.format("(%d,%d)", lo, hi));
}
}
record Rational(int num, int denom) {
// Compact canonical normalizing constructor.
Rational {
int gcd = gcd(num, denom);
num /= gcd;
denom /= gcd;
}
}
JEP 394: Pattern Matching for instanceof
-
Preview: 14
Java programming language is enhanced with pattern matching for the instanceof
operator. The pattern variables use the concept of flow scoping.
if (obj instanceof String s) {
// `String s` is visible here.
}
// `String s` is NOT visible here.
if (!(obj instanceof String s)) {
// `String s` is NOT visible here.
} else {
// `String s` is visible here.
}
JEP 392: Packaging Tool
The jpackage
tool packages a Java application into a platform-specific package that includes all the necessary dependencies supporting the following formats:
-
Linux:
deb
andrpm
-
macOS:
pkg
anddmg
-
Windows:
msi
andexe
jpackage --name myapp --input lib --main-jar main.jar --type pkg
JEP 357: Migrate from Mercurial to Git
The OpenJDK Community’s source code repositories were migrated from Mercurial (hg) to Git.
Java 15
September 2020
JEP 378: Text Blocks
A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way.
-
Preview: 13
final String html = """
{
"message": "Hello world"
}
""";
JEP 377: ZGC: A Scalable Low-Latency Garbage Collector
-
Experimental: 11
Ultra-low latency garbage collector perfect for large heaps and minimal pauses, but increased memory overhead.
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -jar app.jar
java -XX:+UseZGC -jar app.jar
JEP 379: Shenandoah: A Low-Pause-Time Garbage Collector
Low-pause-time garbage collector ideal for responsive applications, but higher CPU usage and complexity.
java -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -jar myapp.jar
java -XX:+UseShenandoahGC -jar myapp.jar
Java 14
March 2020
JEP 358: Helpful NullPointerExceptions
Java gives helpful details about occurred NullPointerException
:
Exception in thread "main" java.lang.NullPointerException:
Cannot assign field "i" because "a" is null
at Prog.main(Prog.java:5)