JEP 443, Unnamed Patterns and Variables (Preview)
Contexte
Les motifs pour les enregistrements (JEP 440 - Records Pattern) permettent justement de déconstruire les enregistrements via leurs composants. De ce fait, nous pouvons avoir des noms et des types de composants qui nous n’intéresse pas. Cela nous devons tout de même les définir.
Voici un exemple avec le code suivant :
record Point(int x, int y) { }
enum Couleur { ROUGE, VERT, BLEU }
record PointColore(Point p, Couleur c) { }
var s = new PointColore(new Point(3,4), Couleur.VERT);
if (r instanceof PointColore(Point p, Couleur c)) { (1)
// nous pouvons utiliser p.x()
// ainsi que p.y()
}
-
Il a été nécessaire de définir la variable
c
de typeCouleur
De leur côté, les variables non utilisées sont liées à la programmation impérative.
Voici un exemple pour le traitement des exceptions :
String chaine = ...;
try {
int entier = Integer.parseInt(chaine);
// On utilise entier
} catch (NumberFormatException ex) { (1)
System.out.println("Chaîne n'est pas un nombre : " + chaine);
}
-
La variable
ex
de typeNumberFormatException
doit être définie même si elle n’est pas utilisée.
Principe
Le principe est d’enrichir le langage java avec les motifs sans nom et les variables sans nom. Les deux pourront être notés par le caractère souligné _
.
C’est une fonctionnatité en mode aperçu.
Pour activer ce mode, je vous conseille cette article JEP 12 - Mode Aperçu
Motifs non utilisés
En reprenant, l’exemple ci-dessus sur les enregistrements, nous pouvons utiliser le caractère souligné _
à la place de la variable non utilisée dans le motif suivant :
if (o instanceof Point(_, int y)) {
// Utilisation de y
...
}
Nous pouvons le faire sur plusieurs niveaux de composition. Ci-dessous on ignore le composant Couleur
:
if (r instanceof PoinColore(Point(int x, int y), _)) { (1)
// Utilisation de x
// et de y
...
}
-
La composant
Couleur
ne nous intéresse pas (le nom et le type)
Inversement, cela peut être seulement la couleur qui nous intéresse?
if (r instanceof PoinColore(_, Couleur c)) {
// Utilisation uniquement de c
...
}
ou uniquement la coordonnée x
de notre point
if (r instanceof PoinColore(Point(int x, _), _)) {
// Utilisation seulement de x
...
}
Variables non utilisées
Déclaration d’affectation
C’est le cas simple de l’affectation où la variable n’est pas utilisée..
Par exemple, une liste de nombre où x1, y1, z1 et consorts. A chaque fois, ceux sont les deux premiers nombres qui sont utiles. Nous pouvons écrire le code suivant::
Queue<Integer> q = ... // x1, y1, z1, x2, y2, z2, ...
while (q.size() >= 3) {
var x = q.remove();
var y = q.remove();
var _ = q.remove();
... new Point(x, y) ...
}
Et si c’est que la valeur x qui est utile, nous aurions donc cela :
while (q.size() >= 3) {
var x = q.remove();
var _ = q.remove();
var _ = q.remove();
... new Point(x, 0) ...
}
Bloc catch
En reprenant l’exemple plus haut, nous n’avons plus besoin de nommer la variable du catch
car nous ne l’utilisons pas.
Cela donne le code suivant ;
String chaine = ...;
try {
int entier = Integer.parseInt(chaine);
// On utilise entier
} catch (NumberFormatException _) {
System.out.println("Chaîne n'est pas un nombre : " + chaine);
}
Cela est aussi valable avec plusieurs bloc catch
.
String chaine = ...;
try {
int entier = Integer.parseInt(chaine);
// On utilise entier
} catch (NumberFormatException _) {
System.out.println("Chaîne n'est pas un nombre : " + chaine);
} catch (NumberFormatException _) {
} catch (Throwable _) {
}
Construction try-with-ressources
Cela donne simplement le code suivant :
try (var _ = ScopedContext.acquire()) {
// Aucun utilisation de la ressource acquis précédemment
...
}
Boucle
Cela est valable pour les boucles si les variables ne sont pas utilisées, comme dans l’exemple ci-dessous :
int acc = 0;
for (Commande _ : commandes) {
if (acc < LIMITE) {
acc++
...
}
}
Lambda
Le caractère souligné _
peut être utilisé si le paramètre non pertinent.
...stream.collect(Collectors.toMap(String::toUpperCase, _ -> "NODATA"))
Histoire du souligné
Le simple souligné _
est une syntaxe valide depuis Java 1.0, dont nous pouvions l’utiliser en tant qu’identifiant.
Le processus qui a permit de réaliser des motifs et variables sans nom aujourd’hui a commencé en 2014 avec Java 8. En effet, à partir de cette version, le compilateur émettait un avertissement si un simple souligné était utilisé comme identifiant.
Puis, en 2017, en java 9 avec la JEP 213: Milling Project Coin, l’avertissement passe à une erreur de compilation pour l’utilisation du simple souligné _
.
Les identifiants commençant par le caractère souligné _
est encore valide (si il est suivi de lettres).
Moteur de recherche
"Eduquer, ce n'est pas remplir des vases mais c'est d'allumer des feux." - Michel Montaigne
Billets récents
- Eclipse plante systématiquement sous Debian (et autres distribution Linux)
- JEP 463, Implicitly Declared Classes and Instance Main Methods (Second Preview)
- Debian - Montée de version de Debian 11 (Bullseye) à Debian 12 (Bookworm)
- JEP 451, Prepare to Disallow the Dynamic Loading of Agents
- JEP 444, Virtual Threads