1. Compréhension simple des génériques
Les génériques sont une nouvelle fonctionnalité de Java SE 1.5. L'essence des génériques est un type paramétré, ce qui signifie que le type de données sur lequel l'opération est effectuée est spécifié en tant que paramètre. Le point populaire est "type variable". Les variables de ce type peuvent être utilisées dans la création de classes, d'interfaces et de méthodes.
Le moyen le plus simple de comprendre les génériques Java est de les considérer comme une syntaxe pratique qui vous évite certaines opérations de conversion Java :
Copiez le code comme suit : List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);
Le code ci-dessus lui-même s'exprime très clairement : box est une liste contenant des objets Apple. La méthode get renvoie une instance d'objet Apple et aucune conversion de type n'est requise dans ce processus. Sans génériques, le code ci-dessus doit être écrit comme ceci :
Copiez le code comme suit : Apple apple = (Apple)box.get(0);
2. L'embarras des génériques
Le plus grand avantage des génériques est qu'ils assurent la sécurité du type de programme et sont rétrocompatibles, mais ils présentent également un point délicat, à savoir que le type du générique doit être spécifié à chaque fois qu'il est défini. Non seulement cela semble un peu verbeux. pour le spécifier explicitement, mais c'est aussi que beaucoup de programmeurs ne sont pas familiers avec les génériques, ils sont donc souvent incapables de fournir des paramètres de type corrects. Désormais, le compilateur peut déduire automatiquement les types de paramètres des génériques, ce qui peut réduire de telles situations et améliorer le code. lisibilité.
3. Améliorations de l'inférence de type générique dans Java 7
Dans les versions précédentes, lorsque vous utilisiez des types génériques, vous deviez ajouter le type générique des deux côtés lors de la déclaration et de l'attribution de valeurs. Par exemple:
Copiez le code comme suit : Map<String, String> myMap = new HashMap<String, String>();
Vous pensez peut-être : j'ai déjà spécifié le type du paramètre lors de la déclaration de la variable, pourquoi dois-je le spécifier à nouveau lors de l'initialisation de l'objet ? Heureusement, dans Java SE 7, cette méthode a été améliorée et vous pouvez désormais déclarer et attribuer des valeurs à l'aide des instructions suivantes :
Copiez le code comme suit : Map<String, String> myMap = new HashMap<>(); //Faites attention au "<>" à la fin.
Dans cette instruction, le compilateur déduira automatiquement le type générique lors de l'instanciation de HashMap en fonction du type générique lorsque la variable est déclarée. Encore une fois, assurez-vous de faire attention au "<>" après le nouveau HashMap. Seul l'ajout de ce "<>" signifie une inférence de type automatique. Sinon, il s'agit d'un HashMap de type non générique, et il sera donné lors de l'utilisation du compilateur. compiler le code source. Une note d'avertissement.
Cependant : l'inférence de type de Java SE 7 lors de la création d'instances génériques est limitée : ce n'est que si le type paramétré du constructeur est explicitement déclaré dans le contexte que l'inférence de type peut être utilisée, sinon elle ne fonctionnera pas. Par exemple : L'exemple suivant ne peut pas être compilé correctement dans Java 7 (mais il peut maintenant être compilé dans Java 8, car le type du générique est automatiquement déduit en fonction des paramètres de la méthode) :
Copiez le code comme suit :
List<String> list = new ArrayList<>();
list.add("A");// Puisque addAll attend un paramètre de type Collection<? extends String>, l'instruction suivante ne peut pas être transmise.
list.addAll(new ArrayList<>());
4. Améliorations de l'inférence de type générique dans Java 8
Il existe deux principaux types d'inférence de type cible pour les génériques dans Java 8 :
1. Prise en charge de la déduction de types de cibles génériques via le contexte de la méthode
2. Prend en charge la transmission de l'inférence de type générique à la dernière méthode de la chaîne d'appel de méthode.
Regardons un exemple tiré du site officiel :
Copiez le code comme suit :
liste de classes<E> {
statique <Z> Liste<Z> nil() { ... } ;
static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
E tête() { ... }
}
D'après les caractéristiques de JEP101, on peut écrire comme ceci en appelant la méthode ci-dessus
Copiez le code comme suit :
// Déduire automatiquement le type du générique via le paramètre cible de l'affectation de méthode
List<String> l = List.nil();
//Au lieu du type spécifié affiché
//Liste<String> l = List.<String>nil();
// Déduire le type du générique via le type de paramètre de méthode précédent
List.cons(42, List.nil());
//Au lieu du type spécifié affiché
//List.cons(42, List.<Integer>nil());
5. Résumé
Ce qui précède est le contenu des fonctionnalités de JEP101. En tant que représentant des langages statiques, Java peut être considéré comme ayant un système de types riche. Le problème de la conversion entre les types dérange tous les programmeurs Java. La déduction automatique des types via le compilateur peut légèrement atténuer le problème d'une conversion de type trop complexe. Bien qu'il s'agisse d'une petite amélioration, cela aura certainement un impact énorme sur nos programmeurs qui écrivent du code tous les jours. Au moins, ils se sentiront plus heureux ~~ Peut-être que dans Java 9, nous aurons un type var universel, comme js ou Certains langages dynamiques. de Scala sont comme ça ^_^