Bonjour à tous et bienvenue dans cet article qui fait suite à celui sur l’inférence de type avec Java 10.
Dans cet article, nous allons voir les améliorations apportées à l’inférence de type dans la prochaine version du langage, Java 11, prévu pour le 25 septembre 2018.
L’inférence de type introduite avec Java 10 avait un certain nombre de limitations, que nous avions déjà évoquées dans des précédents articles (ici et ici).
Java 11, au travers de la JEP 323, propose une extension de l’inférence de type des variables locales aux paramètres des lambdas.
Il est donc maintenant possible de faire :
1 |
IFunc join = (var prefix, var str) -> prefix + str; |
Avantage par rapport au typage implicite
Vous vous demandez peut-être l’interêt que cela peut avoir comparé au typage implicite qui était déjà disponible. Ci-suit une petite comparaison :
1 2 3 4 5 6 7 8 |
// Typage explicite IFunc join = (String prefix, String str) -> prefix + str; // Typage implicite IFunc join = (prefix, str) -> prefix + str; // Inférence de type IFunc join = (var prefix, var str) -> prefix + str; |
En effet, la syntaxe avec l’inférence n’est pas spécialement plus pratique que le typage implicite dans un cas comme celui-ci. On pourrait arguer que var a l’avantage de proposer une syntaxe uniforme avec les autres variables locales.
Cependant, contrairement au typage implicite, l’usage de l’inférence de type permet l’utilisation de modificateurs et d’annotations. C’est une des raisons qui ont poussé à son adoption avec Java 11 :
1 2 3 4 5 6 7 8 |
// Typage explicite IFunc join = (@Nonnull final String prefix, @Nullable String str) -> prefix + str; // Typage implicite // illegal : IFunc join = (@Nonnull final prefix, @Nullable str) -> prefix + str; // Inférence de type IFunc join = (@Nonnull final var prefix, @Nullable var str) -> prefix + str; |
Dans le cas d’utilisation de types complexes, il est largement préférable encore une fois d’utiliser l’inférence de type que le typage explicite :
1 2 3 4 5 |
// Java 10 IFunc f = (@NonNull MyVeryVeryComplexAndLongClassName x, final AnotherVeryLongAndComplexClassName y) -> Foo.foo(x, y); // Java 11 IFunc f = (@NonNull var x, final var y) -> Foo.foo(x, y); |
Limitation
La proposition indique quelques limitations concernant cette fonctionnalité. Premièrement, il n’est pas autorisé de mélanger les différentes techniques :
1 2 |
(var x, y) -> x.process(y) // error : cannot mix 'var' and 'no var' in implicitly typed lambda expression (var x, int y) -> x.process(y) // error : cannot mix 'var' and manifest types in explicitly typed lambda expression |
De plus, il n’est pas possible d’omettre les parenthèses avec l’inférence de type comme c’est le cas avec le typage implicite :
1 2 3 4 5 |
// Typage implicite x -> x.doSomething() // Inférence de type var x -> x.doSomething() // illegal |
Cette petite amélioration de Java 11 va donc permettre de largement simplifier l’usage des lambdas lorsqu’on utilise des types complexes associés à des annotations ou des modificateurs tels que final et d’uniformiser les déclarations de variables locales.
Merci d’avoir lu cet article, et à bientôt :).
You must log in to post a comment.