Aller au contenu
BackJava

Quoi de neuf dans l'API Java 21 ?

Java 21 est sorti en septembre 2023 et embarque une quinzaine de JEP. Voici un tour d'horizon de ses nouveautés.

Java 2

Java 21 est sorti ! Outre le fait qu'il s'agisse d'une version LTS (Long Term Support), celle-ci est riche en innovations. Difficile de vous y retrouver ? Examinons cela en détail.

Nouveautés de l'API

Ces fonctionnalités sont d'ores et déjà opérationnelles dans Java 21.

Sequenced Collections (JEP 431)

Enfin, un renouvellement de l'API Collection ! Il manquait effectivement la notion de collections ordonnées. Trois nouvelles interfaces sont introduites dans cette mouture :

  • SequencedCollection
  • SequencedSet
  • SequencedMap

Elles proposent des méthodes communes et cohérentes pour manipuler ou ajouter les éléments en début ou en fin de liste.

Diagramme de classes Collection API

Notons que l'objet ArrayList, qui implémentait déjà List, est dorénavant également une SequencedCollection.

Record Pattern (JEP 440)

Précédemment en phase de preview, cette fonctionnalité est désormais officielle et autorise la déconstruction d'un record pour accéder à ses sous-composants. En Java 16, le Pattern Matching nous permettait déjà de simplifier l'écriture d'un instanceof en évitant le cast.

if(o instanceof String){
    String s = (String)o;
    System.out.println(s);
}

Devenait alors :

if(o instanceof String s){
    System.out.println(s);
}

On va utiliser la structure des Records pour les déconstruire et accéder aux champs directement :

record Point(int x, int y) {}

if(o instanceof Point(int a, int b)){
    int c = a + b;
}

Ca marche aussi dans un switch

int c = switch (o){
    case Point(int a, int b) -> a + b
    ...
}

Threads Virtuels (JEP 444)

C'est LA nouveauté attendue par tous, qui sort enfin de sa phase de preview ! Pour en savoir plus, je vous renvoie à mon article précédent.

Autres ajouts

Mentionnons quelques autres petites nouveautés intéressantes :

  • Gestion des Emoji : Character.isEmoji() entre autres
  • StringBuilder.repeat() pour répéter une String
  • HttpClient implémente AutoClosable et peut être utiliser dans un bloc try with resource

Nouveautés en Preview

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 21 --enable-preview

lors de la compilation, et

--enable-preview

lors du run

String Templates (JEP 430)

Permet d'intégrer des expressions qui seront interpolées dans les chaînes de caractères. Si beaucoup de langages supportent déjà cette fonctionalité, Java permet de le rendre safe grâce à des étapes de validation nettoyage via un Template Processor. On peut ainsi se protéger des injection SQL par exemple.

Un Template Processor prend un template, et l'interpole vers un autre objet. On peut ainsi interpoler vers une String, un PreparedStatement, un JSONObject...

String str = "World"
String result = STR."Hello \{str}";

On utilise une expression avec la notation \{expression} et on appelle un Processor avec sont nom, ici STR, qui est une constante de la classe StringTemplate, qu'on importe de façon statique.

Le JDK apporte 3 Processors

  • RAW : n'interpole pas les expression
  • STR : interpole une String vers une String par concaténation
  • FMT : interpole une String vers une String en autorisant le formattage via un Formatter
String log = FMT."%d\{a} + %d\{b} = %d\{a + b}

Il est possible de créer son propre Processor en implémentant l'interface StringTemplate.Processor

Variables et Patterns anonymes (JEP 443)

Cela arrive régulièrement de devoir déclarer une variable alors qu'elle est inutile. Dans le cas du catch d'exception ou d'une lambda par exemple. Cette nouveauté permet de ne pas avoir à la nommer en utilisant le caractère '_' (underscore).

//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<>());

On peut aussi l'utiliser dans les Pattern Matching

if(object instanceof Point(int _, int y)){
	...
}

int n = switch(obj){
	case Point(int x, int _) -> x
}

Unnamed Classes et Instance Main method (JEP 445)

Le but de cette JEP est de faciliter l'apprentissage de Java et de rendre optionnel tout ce qui nécessite de créer une méthode main, pour n'avoir à la fin que la méthode la plus simple possible. Par exemple, aujourd'hui, on écrit :

public class HelloWorld { 
    public static void main(String[] args) { 
        System.out.println("Hello World!");
    }
}

Pour écrire Hello World dans la console, il faut décrire une grande quantité de concepts : classe, visibilité, static, la signature spécifique de main avec son tableau de String. On simplifie d'abord en enlevant la visibilité, le static et les paramètres :

class HelloWorld { 
    void main() { 
        System.out.println("Hello World!");
    }
}

Enfin, on simplifie encore plus avec la notion de classe anonyme :

    void main() { 
        System.out.println("Hello World!");
    }

Une classe anonyme est un fichier .class qui n'a pas de déclaration de classe, ne peut pas être appelé par une autre classe, mais peut contenir des méthodes et des champs. Cela permet de faciliter l'écriture de la méthode main, et est surtout tournée pour un apprentissage du langage.

Liste officielle

Il y a encore d'autres nouveautés dans cette version, retrouvez la release note complète de Java 21.

Finalement, la version 21 de Java apporte un éventail de nouveautés intéressantes, desquelles on pourrait passer à côté si l'on se focalisait exclusivement sur les threads virtuels. De surcroît, il s'agit d'une version LTS : vous n'avez donc aucune excuse pour ne pas l'employer dans vos nouveaux projets.

Dernier