Le mot clé var introduit en Java 10

Java 10 est sorti il y a quelques semaines et la nouveauté la plus visible pour le développeur est l’introduction du mot clé var, lié à l’inférence de type des variables locales. Découvrons ce qui se cache derrière cette notion, comment l’utiliser et surtout quand ne pas l’utiliser !

J’utilise pour cet article openJDK-10.0.1 et le shell interactif jshell en mode verbose pour avoir la description des types inférés.

L’introduction du mot clé var est décrite dans la JEP 286. Son intérêt, pour reprendre les mots de l’auteur (Brian Goetz) est “d’améliorer l’expérience de développement en réduisant le cérémonial autour de l’écriture de code Java” ( En anglais dans le texte : « improve the developer experience by reducing the ceremony associated with writing Java code »)
Ce n’est pas un mot clé du langage, mais un nom de type réservé, c’est à dire que l’on ne peut plus appeler une classe var, c’était de toute manière une façon bien maladroite de nommer une classe, mais on peut toujours appeler une variable var.
Pas de let. Java reste typé statiquement, l’inférence de type est faite à la compilation, le bytecode généré est exactement le même que lorsque le type est explicité, ce qui assure qu’il n’y a pas d’impact sur la performance.
Pas de val, const, etc. non plus, les variables locales ne sont pas le meilleur endroit pour définir des constantes et Java possède déjà la notion de variable effectivement finale depuis Java 8. Il faut donc écrire final var pour expliciter une variable finale.

La syntaxe

Remarque : le shell interactif ne nécessite pas de ; à la fin des lignes.

On a ainsi créé une variable locale i de type entier initialisée à 0. La valeur d’initialisation est obligatoire, c’est elle qui permet l’inférence de type.

La variable déclarée peut ensuite être lu ou modifiée classiquement.

Utilisation

On peut utiliser le mot clé var seulement pour des variables locales (pas pour les arguments d’une méthode, ni son type de retour, ni un attribut de classe).
On peut donc les utiliser dans une boucle for.

Plus intéressant avec les collections :

Enfin un avantage, plus besoin de déclarer la variable d’itération comme un Entry<String, String> !!

On remarque également que le type d’annuaire est HashMap, celui de l’implémentation réelle fournie comme valeur d’initialisation.

On a bien accès aux méthodes de la classe TreeSet. Le type inféré par le mot clé var est celui de l’implémentation.

Utilisation avec une factory

Le cas sans doute le plus intéressant.

Avant :

Après :

L’écriture est effectivement simplifiée, attention toutefois à ne l’utiliser que lorsque l’information de type perdue n’est pas importante.

On pourrait objecter également qu’utiliser une map de liste n’est pas une bonne idée… une telle utilisation doit être justifiée, primitive obsession smell.

var avancé

Que peut-on faire de plus avec var ?

Nous déclarons une instance p d’une classe anonyme.

L’inférence de type, assigne le type réel à la variable p, ce qui nous permet d’accéder aux attributs déclarés dans la classe anonyme !
Cette nouvelle possibilité ouvre de nombreuses perspectives, au niveau de l’écriture d’un code potentiellement plus clair, ce n’est toutefois pas une révolution.

var et les collections

Ici on remarque que le type du constructeur est List, ce qui est le type inféré grâce au type de retour de la factory of. Sans surprise, on a une List<Integer>.

L’intérêt est ici évident, jamais je n’aurais envie d’écrire ce type manuellement. On peut être surpris par le Number&Comparable<...> mais en Java, Number n’implémente pas Comparable, le compareTo étant implémenté dans chaque classe fille.

Pour une réponse plus complète, voir la mutabilité des AtomicXXX et ce lien.

Un autre exemple qui montre le fonctionnement de l’inférence de type.

var VS 💎 (opérateur diamant)

L’information n’est ni sur var, ni sur le <>, le compilateur ne fait pas de miracle.

Le type inféré est Object 🙁

var et les lambdas

En un mot, NON.
Les lambdas ne peuvent être déclarées par le mot clé var, le type d’une lambda dépendant du type de la variable à laquelle on l’assigne.

La réponse du compilateur est explicite !

Conclusion

Le mot clé var n’est pas une révolution, mais il permet tout comme l’opérateur <> d’améliorer la lisibilité de certains codes.
Il faut par contre se montrer encore plus vigilant au nommage et à la portée des variables lorsqu’on l’utilisera.
Ce mot clé n’est pas magique et ne fonctionne pas avec les lambdas: il faut choisir entre var et l’opérateur diamant lors d’une utilisation avec les collections.
Enfin le type inféré est celui de l’implémentation lors de la création via new et demande un soin particulier pour ne dépendre que de l’interface (même dans le corps d’une méthode, dépendre d’une implémentation est une mauvaise pratique).
Permettre l’accès aux attributs d’une classe anonyme est un bonus, l’usage n’en est toutefois pas certain.

1 commentaire

  • Sympa ! Ça fait maintenant quelques années que j’ai « quitté » le dev Java et ça fait plaisir de voir un tel mot clé implémenté ! A savoir si dans l’utilisation ça ne rend effectivement pas le code « moins lisible » à force de l’utiliser partout 🙂

Laisser un commentaire

MERITIS ICI. ET LÀ.

Carte Meritis

Meritis Finance

5 – 7, rue d’Athènes
75009 Paris

+33 (0) 1 86 95 55 00

contact@meritis.fr

Meritis PACA

Les Algorithmes – Aristote B
2000 Route des Lucioles
06901  Sophia Antipolis Cedex

+33 (0) 4 22 46 31 00

contact@meritis-paca.fr

Meritis Technologies

5 – 7, rue d’Athènes
75009 Paris

contact@meritis-technologies.fr

+33 (0) 1 86 95 55 00


Contactez-nous