Inférence généralisée de type cible en Java
1. introduction
Le type inférence a été introduit dans Java 5 pour compléter l’introduction des génériques et a été considérablement étendu dans les versions suivantes de Java, également désignée sous le nom d’inférence généralisée de type cible.
Dans ce didacticiel, nous allons explorer ce concept avec des exemples de code.
2. Génériques
Les génériques nous ont apporté de nombreux avantages, tels qu'une sécurité de type accrue, l'élimination des erreurs de transtypage et des algorithmes génériques. Vous pouvez en savoir plus sur les génériques dans cearticle.
Cependant, l'introduction degenerics resulted in the necessity of writing boilerplate code due to the need to pass type parameters. Certains exemples sont:
Map> mapOfMaps = new HashMap>();
List strList = Collections.emptyList();
List intList = Collections.emptyList();
3. Tapez Inference Before Java 8
Pour réduire la verbosité inutile du code due, l'inférence de type a été introduite dans Java qui is the process of automatically deducing unspecified data types of an expression based on the contextual information.
Nous pouvons maintenant appeler les mêmes types et méthodes génériques sans spécifier les types de paramètres. Le compilateur déduit automatiquement les types de paramètres si nécessaire.
Nous pouvons voir le même code en utilisant le nouveau concept:
List strListInferred = Collections.emptyList();
List intListInferred = Collections.emptyList();
Dans l'exemple ci-dessus, en fonction des types de retour attendusList<String> etList<Integer>, le compilateur peut déduire le paramètre type de la méthode générique suivante:
public static final List emptyList()
Comme on peut le constater, le code résultant est concis. Now, we can call generic methods as an ordinary method if the type parameter can be inferred.
En Java 5, nous pourrions faire une Type-Inference dans des contextes spécifiques, comme indiqué ci-dessus.
Java 7 a étendu les contextes dans lesquels cela pourrait être effectué. Il a introduit l'opérateur diamant<>. Vous pouvez en savoir plus sur l'opérateur diamant dans cearticle.
Maintenant,we can perform this operation for generic class constructors in an assignment context. Un tel exemple est:
Map> mapOfMapsInferred = new HashMap<>();
Ici, le compilateur Java utilise le type d'affectation attendu pour déduire les paramètres de type du constructeurHashMap.
4. Inférence généralisée de type cible - Java 8
Java 8 a encore étendu la portée de l'Inférence de types. Nous faisons référence à cette capacité d'inférence étendue en tant qu'inférence généralisée de type cible. Vous pouvez lire les détails techniqueshere.
Java 8 a également introduit les expressions Lambda. Lambda Expressions do not have an explicit type. Their type is inferred by looking at the target type of the context or situation. Le type cible d'une expression est le type de données attendu par le compilateur Java en fonction de l'endroit où l'expression apparaît.
Java 8 prend en charge l'inférence en utilisant Target-Type dans un contexte de méthode. When we invoke a generic method without explicit type arguments, the compiler can look at the method invocation and corresponding method declarations to determine the type argument (or arguments) that make the invocation applicable.
Regardons un exemple de code:
static List add(List list, T a, T b) {
list.add(a);
list.add(b);
return list;
}
List strListGeneralized = add(new ArrayList<>(), "abc", "def");
List intListGeneralized = add(new ArrayList<>(), 1, 2);
List numListGeneralized = add(new ArrayList<>(), 1, 2.0);
Dans le code,ArrayList<> ne fournit pas explicitement l'argument de type. Le compilateur doit donc en déduire. Tout d'abord, le compilateur examine les arguments de la méthode add. Ensuite, il examine les paramètres transmis lors d'appels différents.
It performs invocation applicability inference analysis to determine whether the method applies to these invocations. Si plusieurs méthodes sont applicables en raison d'une surcharge, le compilateur choisira la méthode la plus spécifique.
Ensuite,the compiler performs invocation type inference analysis to determine the type arguments.The expected target types are also used in this analysis. Il déduit les arguments dans les trois instances commeArrayList<String>,ArrayList<Integer> etArrayList<Number>.
L'inférence Target-Type nous permet de ne pas spécifier de types pour les paramètres d'expression lambda:
List intList = Arrays.asList(5, 2, 4, 2, 1);
Collections.sort(intList, (a, b) -> a.compareTo(b));
List strList = Arrays.asList("Red", "Blue", "Green");
Collections.sort(strList, (a, b) -> a.compareTo(b));
Ici, les paramètresa etb n'ont pas de types explicitement définis. Leurs types sont déduits commeInteger dans la première expression Lambda et commeString dans la seconde.
5. Conclusion
Dans cet article rapide, nous avons examiné Type Inference, qui, associé aux génériques et à l’expression Lambda, nous permet d’écrire du code Java concis.
Comme d'habitude, le code source complet peut être trouvéover on Github.