Java 10 var et capture variable

Je lis le JEP 286 mais je ne comprends pas cette partie:

Les variables de capture, et les types avec des variables de capture nestedes, sont projetés dans des supertypes qui ne mentionnent pas les variables de capture. Ce mappage remplace les variables de capture par leurs limites supérieures, ainsi que les arguments de type mentionnant les variables de capture avec des caractères génériques liés (puis se reproduit). Cela préserve la scope traditionnellement limitée des variables de capture, qui ne sont sockets en compte que dans une seule instruction.

Quelqu’un peut-il me donner un exemple concret en code Java de ce qu’il signifie?

var vous permet d’inférer un type non dénotable:

 var x = new Object() { int i = 10; }; System.out.println(xi); // works; `x` has the non-denotable type of the annonymous class 

Donc, théoriquement, cela vous permettrait de déduire un type générique. Mais ce que dit ce texte, c’est que ce n’est pas possible, car le caractère générique est remplacé par sa limite supérieure ou par une nouvelle variable de capture dans le type inféré.

Prenons par exemple cet extrait de code:

 List l1 = new ArrayList<>(); l1.add("Hello"); List l2 = l1; var x = l2.get(0); l2.add(x); // error 

Ici, au lieu que le type de x soit inféré au type exact du caractère générique, la dernière ligne serait compilée. Au lieu de cela, il est déduit de sa limite supérieure, qui est Object , et vous obtenez le message d’erreur (Eclipse):

 The method add(capture#2-of ?) in the type List is not applicable for the arguments (Object) 

Où vous pouvez voir que le type de x est Object .

C’est la partie

Ce mappage remplace les variables de capture par leurs limites supérieures


La seconde partie

… et remplace les arguments de type mentionnant les variables de capture par des caractères génériques liés

Parle d’une situation comme celle-ci:

 List l1 = new ArrayList<>(); l1.add("Hello"); List l2 = l1; var l3 = l2; // type of 'l3' is List, but not the same '?' as 'l2' l3.add(l2.get(0)); // error 

Cela ne comstack pas non plus, car le type de l3 n’est pas exactement le même type que le type de l2 , ce qui signifie que le type renvoyé par l2.get(0) n’est pas du même type que celui requirejs par l3.add(...) . L’erreur ici est:

 The method add(capture#2-of ?) in the type List is not applicable for the arguments (capture#3-of ?) 

Et vous voyez que les deux variables de capture sont distinctes, ce qui signifie que le type de l3 n’est pas exactement le type de l2 , mais que la variable de capture du type de l2 dans le type inféré est remplacée par un caractère générique avec la même limite, car une nouvelle variable de capture est ensuite créée.

Donc, pour un type List Le type inféré est List , Puis le compilateur crée une nouvelle variable de capture pour ce caractère générique, générant List (Bien que la numérotation puisse en pratique, la clé est que les 2 variables de capture sont différentes).