> ## Content Index
> Fetch the complete content index at: https://www.sfeir.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Quoi de neuf dans l'API Java 21 ?
- URL: https://www.sfeir.dev/back/quoi-de-neuf-dans-lapi-java-21/
- Published: 2023-10-06T09:17:03.000Z
- Updated: 2024-01-23T08:51:25.000Z
- Description: Java 21 est sorti en septembre 2023 et embarque une quinzaine de JEP. Voici un tour d'horizon de ses nouveautés.
- Author: Yves Dautremay
- Tags: Back, Java

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](https://openjdk.org/jeps/431?ref=sfeir.dev))

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. 

![](https://storage.ghost.io/c/0b/31/0b31478e-a66a-46f1-8c34-d44388e21192/content/images/2023/10/SequencedCollectionDiagram20220216.png)

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](https://openjdk.org/jeps/440?ref=sfeir.dev))

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.

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

Devenait alors :

```java
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 :

```java
record Point(int x, int y) {}

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

Ca marche aussi dans un switch

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

### Threads Virtuels ([JEP 444](https://openjdk.org/jeps/444?ref=sfeir.dev))

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](https://www.sfeir.dev/back/revolutionnez-votre-programmation-asynchrone-avec-java-21-et-loom/).

### 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](https://openjdk.org/jeps/430?ref=sfeir.dev))

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*...

```java
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*

```java
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](https://openjdk.org/jeps/443?ref=sfeir.dev))

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). 

```java
//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

```java
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](https://openjdk.org/jeps/445?ref=sfeir.dev))

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 :

```java
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 :

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

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

```java
    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](https://jdk.java.net/21/release-notes?ref=sfeir.dev).

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.