Maintenant que les fonctionnalités de Java 22 ont été fixées ( Rampdown Phase Two), il est temps de regarder ce que nous prépare cette nouvelle édition "features".
La sortie de Java 22 est prévue pour le 19 mars 2024. Si vous avez raté les nouveautés de Java 21, vous pouvez aller lire mon article sur le sujet.
Les nouveautés de l'API qui sortent de preview
Ces fonctionnalités étaient en preview dans les versions précédentes et seront utilisables en Java 22.
Variables et Patterns anonymes (JEP 456)
Permet l'utilisation du caractère '_' pour déclarer des variables anonymes. C'est très utile quand la déclaration de variable est obligatoire, mais que la variable est inutile. Par exemple :
//Variable locale d'un statement
for(Element _ : elements){
//Bloc qui n'utilise pas les élément
}
var _ = mySet.remove(myObject);
//Bloc catch
try{
int i = Integer.parseInt(str);
}catch(NumberFormatException _){
logger.warn("Not a number");
}
//Lambda
Map<EmployeeId, List<Employee>> employees = new HashMap<>();
employees.computeIfAbsent(id, _ -> new ArrayList<>());
ou dans un pattern matching :
if(object instanceof Point(int _, int y)){
...
}
int n = switch(obj){
case Point(int x, int _) -> x
}
Foreign Function & Memory API (JEP 454)
Cette API donne accès a des outils pour appeler du code natif. Elle permet l'invocation de fonctions hors de la JVM (librairies C par exemple) ainsi que la gestion de la mémoire hors de la JVM. Cette API se veut bien plus simple et robuste d'utilisation que l'utilisation de JNI.
Nouveautés côté Tooling et Garbage Collector
Region Pinning for G1 (JEP 423)
Cette amélioration du garbage collector permet d'éviter le blocage de threads lors du passage sur les zones de mémoire critiques venant de l'utilisation de JNI.
Exécution directe de code source avec fichiers multiples (JEP 458)
Depuis Java 11, il est possible d'exécuter directement du code source sans le compiler avant. Java s'occupant lui même de cette étape à la volée. La contrainte étant que tout le programme soit contenu dans le même fichier.
class Prog {
public static void main(String[] args) { Helper.run(); }
}
class Helper {
static void run() { System.out.println("Hello!"); }
}
On lance ensuite :
$ java Prog.java
Java va compiler le code en mémoire et l'exécuter.
En Java 22, il sera possible de faire cette manipulation même si le programme a ses classes dans plusieurs fichiers. Java ira chercher les fichiers en suivant les packages déclarés.
Et beaucoup de preview/incubations
Ces fonctionnalités ne sont pas activées par défaut et nécessitent l'ajout de flags lors de la compilation. Pour les activer il faut ajouter les flags :
--release 22 --enable-preview
lors de la compilation, et :
--enable-preview
lors du run.
Statement before super (JEP 447)(Preview)
Cette fonctionnalité permet, dans un constructeur, d'écrire du code avant d'appeler super(). On imagine vouloir valider des arguments spécifiques à une sous classe avant d'appeler le constructeur parent, ce qui pourrait être inutile.
public class PositiveBigInteger extends BigInteger {
public PositiveBigInteger(long value) {
if (value <= 0)
throw new IllegalArgumentException("non-positive value");
super(value);
}
}
Stream Gatherers (JEP 461) (Preview)
Une nouveauté dans l'API Stream ! Cette opération intermédiaire permet de modifier le stream en profondeur. Il n'existe pas aujourd'hui d'opérateur intermédiaire permettant de modifier simplement le contenu du stream avec un impact sur sa taille. Le combo filter/map peut ne pas être suffisant. L'API gathere propose de remplir ce manque. Elle propose des Gatherers built-in comme par exemple une fenêtre glissante :
// will contain: [[1, 2, 3], [4, 5, 6], [7, 8]]
List<List<Integer>> windows =
Stream.of(1,2,3,4,5,6,7,8).gather(Gatherers.windowFixed(3)).toList();
Nous en reparlerons lors de sa sortie de preview, mais cela semble dors et déjà très intéressant.
Class-File API (JEP 457)(Preview)
Cette API propose un standard pour parser, générer ou transformer des fichiers .class (le bytecode). Nous pourrons utiliser cette API plutôt que d'utiliser une librairie comme javassist.
String templates (JEP 459)(2nd Preview)
Nous en avons déjà parlé lors de la sortie de Java 21. Cette fonctionnalité permet de créer des templates de String et de les valoriser de manière sûre.
String str = "World"
String result = STR."Hello \{str}";
Pas de changement notable dessus.
Vector API (JEP 460) (7e Incubation)
Cette API, en incubation depuis Java 16, promet de faire des calculs réellement parallèles sur les CPU qui proposent des instructions de calcul vectoriel.
Structured Concurrency (JEP 462) (2nd Preview)
Cette nouvelle API permet de simplifier l'écriture de code multi-threadé en traitant plusieurs tâches concurrentes comme une seule unité de traitement. Au cœur de l'API, on trouve la classe StructuredTaskScope qui décrit une tâche à lancer en arrière plan, puis permet de récupérer son résultat.
Response handle() throws ExecutionException, InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Supplier<String> user = scope.fork(() -> findUser());
Supplier<Integer> order = scope.fork(() -> fetchOrder());
scope.join() // Join both subtasks
.throwIfFailed(); // ... and propagate errors
// Here, both subtasks have succeeded, so compose their results
return new Response(user.get(), order.get());
}
}
Ici on lance deux tâches en parallèle : findUser() et fetchOrder(), puis on attend les résultats pour les renvoyer. On notera la gestion simple des erreurs.
Implicitly Declared Classes and Instance Main Methods (JEP 463) (2nd Preview)
Cette fonctionnalité fait suite à celle que l'on a vu dans Java 21 en 1ère Preview (Unnamed Classes et Instance Main method) et qui permet de déclarer une méthode main avec une facilité déconcertante, surtout utile lors de l'apprentissage du langage.
void main() {
System.out.println("Hello, World!");
}
Ci-dessus le contenu complet du fichier java, on notera l'absence des mots-clés class, public, static, String[]
Scoped Values (JEP 464) (Second Preview)
Cette fonctionnalité permet de partager des données entre des Threads lancés dans un même scope. Son utilisation se veut plus facile que ThreadLocal, ce dernier étant peu compatible avec thread virtuels, introduit dans Java 21.
Conclusion
On note donc qu'une seule nouveauté d'API sortant de Preview au menu de cette version. Elle se veut plutôt pratique puisqu'elle introduit les caractères '_' pour des variables anonymes.
La bonne nouvelle c'est qu'il y a beaucoup de choses en preview avec lesquelles s'amuser et expérimenter pendant ces longues soirées d'hiver 🥶