JDK 19 was released on Sep 20, 2022. Below are the important features in Java 19 that can be used in development.
-
System properties for System.out and System.err-
An existing Java application can be run with JDK 19. Some question marks can be seen on the console instead of special characters.
In JDK 19, the operating system's default encoding is used for printing to System.out and System.err "Cp1252" on Windows. To change the output to UTF-8, the below options must be added when calling the java application:
-Dstdout.encoding=utf8 -Dstderr.encoding=utf8
To avoid performing this step every time the program starts, set these settings globally by defining the below environment variable:
_JAVA_OPTIONS="-Dstdout.encoding=utf8 -Dstderr.encoding=utf8"
-
Methods to create preallocated HashMaps for collection -
To create an ArrayList size for a known number of elements (like 60), the following should be followed:
List<String> list = new ArrayList<>(60);
The array underlying the ArrayList is allocated directly for 60 elements and do not have to be enlarged several times to insert the 60 elements.
Similarly, to be able to generate a HashMap as below:
Map<String, Integer> map = new HashMap<>(60);
HashMap offers volume for 60 entries as the HashMap is initialized with a default load factor of 0.75. It means that as soon as the HashMap is 75% full, it is rebuilt (rehashed) with double the size ensuring elements are distributed as even as possible across the HashMap's buckets and that as few buckets as possible contain more than one element.
The HashMap initialized with a capacity of 60 can only hold 60 × 0.75 = 45 mappings.
To create a HashMap for 60 entries, capacity must be calculated by dividing the number of mappings by the load factor: 60 ÷ 0.75 = 80.
Therefore, a HashMap for 60 entries has to be created as below:
// for 60 mappings: 60 / 0.75 = 80
Map<String, Integer> map = new HashMap<>(80);
In JDK 19, the following can be written:
Map<String, Integer> map = HashMap.newHashMap(60);
Examining the source code of the new methods carefully, we find that they do the same as before in jdk8:
public static <K, V> HashMap<K, V> newHashMap(int numMappings) {
return new HashMap<>(calculateHashMapCapacity(numMappings));
}
static final float DEFAULT_LOAD_FACTOR = 0.75f;
static int calculateHashMapCapacity(int numMappings) {
return (int) Math.ceil(numMappings / (double) DEFAULT_LOAD_FACTOR);
}
The newHashMap() method has also added to LinkedHashMap and WeakHashMap. -
Pattern Matching for switch-
In Java 17, ‘Pattern Matching for switch’ enabled writing code like the following:
switch (obj) {
case String str && str.length() > 5 -> System.out.println(str.toUpperCase());
case String str -> System.out.println(str.toLowerCase());
case Integer i -> System.out.println(i * i);
default -> {}
}If an object is of a particular class and if it has extra features can be checked within a switch statement.
In Java 19, JDK Enhancement 427 changed the syntax of the so-called ’Guarded Pattern’. Instead of &&, the new keyword must be used when is a so-called ’contextual keyword’ and only has a meaning within a case label.
- switch (obj) {
case String str when s.length() > 5 -> System.out.println(str.toUpperCase());
case String str -> System.out.println(str.toLowerCase());
case Integer i -> System.out.println(i * i);
default -> {}
}
If there are variables or methods with the name ’when’ in the application, it is not required to be changed.
- switch (obj) {
-
Use Object with switch-
From Java 17, the original can be written as a switch statement:
private void display(Object object) {
switch (object) {
case Calculate calci
-> System.out.println("object is a calci, x = " + calci.getNumber() + ", y = " + calci.getAge());
// other cases ...
}
} -
The following can also be used in the switch case statement:
private void display(Object object) {
switch (object) {
case Position(int x, int y)
-> System.out.println("object is a position, x = " + x + ", y = " + y);
// other cases ...
}
}
References –
https://www.oracle.com/java/technologies/javase/19-relnote-issues.html