Ne pas avoir besoin de typage est l'un des plus grands avantages des génériques Java. car il effectue une vérification des types au moment de la compilation. Cela réduira la possibilité de ClassCastException
qui peuvent être lancés au moment de l'exécution, et peuvent conduire à un code plus robuste.
Mais je soupçonne que vous en êtes pleinement conscient.
Chaque fois que je regarde les génériques, ça me donne un mal de tête. Je trouve que la meilleure partie de Java est sa simplicité et sa syntaxe minimale syntaxe minimale et les génériques ne sont pas simples et ajoutent une quantité significative de nouvelle syntaxe.
Au début, je ne voyais pas non plus l'avantage des génériques. J'ai commencé à apprendre Java à partir de la syntaxe 1.4 (même si Java 5 était sorti à l'époque) et lorsque j'ai rencontré les génériques, j'ai eu l'impression que c'était plus de code à écrire, et je n'ai pas vraiment compris les avantages.
Les IDE modernes facilitent l'écriture de code avec des génériques.
La plupart des IDE modernes et décents sont suffisamment intelligents pour aider à écrire du code avec des génériques, en particulier avec la complétion de code.
Voici un exemple de création d'un Map<String, Integer>
avec un HashMap
. Le code que je devrais taper est :
Map<String, Integer> m = new HashMap<String, Integer>();
Et en effet, cela fait beaucoup de choses à taper juste pour faire une nouvelle HashMap
. Cependant, en réalité, je n'ai eu qu'à taper autant de mots pour qu'Eclipse sache ce dont j'avais besoin :
Map<String, Integer> m = new Ha
Ctrl + Space
C'est vrai, j'ai dû sélectionner HashMap
à partir d'une liste de candidats, mais en fait, l'IDE savait ce qu'il fallait ajouter, y compris les types génériques. Avec les bons outils, utiliser des génériques n'est pas si difficile.
De plus, puisque les types sont connus, lors de la récupération d'éléments de la collection générique, l'IDE agira comme si cet objet était déjà un objet de son type déclaré -- il n'est pas nécessaire de faire un casting pour que l'IDE sache quel est le type de l'objet.
L'un des principaux avantages des génériques réside dans la manière dont ils s'adaptent aux nouvelles fonctionnalités de Java 5. Voici un exemple d'introduction de nombres entiers dans un fichier Set
et de calculer son total :
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(42);
int total = 0;
for (int i : set) {
total += i;
}
Dans ce morceau de code, trois nouvelles fonctionnalités de Java 5 sont présentes :
Premièrement, les génériques et l'autoboxage des primitives permettent les lignes suivantes :
set.add(10);
set.add(42);
Le nombre entier 10
est autoboxé dans un Integer
avec la valeur de 10
. (Et pareil pour 42
). Alors que Integer
est jeté dans le Set
qui est connu pour tenir Integer
s. Essayer d'ajouter un String
provoquerait une erreur de compilation.
Ensuite, la boucle for-each prend les trois :
for (int i : set) {
total += i;
}
Tout d'abord, le Set
contenant Integer
sont utilisés dans une boucle for-each. Chaque élément est déclaré comme étant un int
et cela est autorisé comme le Integer
est ramené à la primitive int
. Et le fait que cet unboxing se produise est connu parce que generics a été utilisé pour spécifier qu'il y avait des Integer
tenues dans les Set
.
Les génériques peuvent être la colle qui rassemble les nouvelles fonctionnalités introduites dans Java 5, et cela rend le codage plus simple et plus sûr. Et la plupart du temps, les IDE sont suffisamment intelligents pour vous aider avec de bonnes suggestions, donc en général, il n'y aura pas beaucoup plus de saisie.
Et franchement, comme on peut le voir dans les Set
Par exemple, je pense que l'utilisation des fonctionnalités de Java 5 peut rendre le code plus concis et plus robuste.
Edit - Un exemple sans génériques
Voici une illustration de ce qui précède Set
exemple sans l'utilisation de génériques. C'est possible, mais ce n'est pas vraiment agréable :
Set set = new HashSet();
set.add(10);
set.add(42);
int total = 0;
for (Object o : set) {
total += (Integer)o;
}
(Remarque : le code ci-dessus générera un avertissement de conversion non vérifié au moment de la compilation).
Lorsque l'on utilise des collections non génériques, les types qui sont introduits dans la collection sont des objets de type Object
. Par conséquent, dans cet exemple, une Object
est ce qui est en train d'être add
dans l'ensemble.
set.add(10);
set.add(42);
Dans les lignes ci-dessus, l'autoboxing est en jeu -- la primitive int
valeur 10
et 42
sont transportés par autobus dans Integer
qui sont ajoutés à la Set
. Cependant, gardez à l'esprit que le Integer
sont traités comme des objets Object
car il n'y a pas d'information de type pour aider le compilateur à savoir de quel type sont les Set
doit s'attendre.
for (Object o : set) {
C'est la partie qui est cruciale. Si la boucle for-each fonctionne, c'est parce que la boucle Set
met en œuvre la Iterable
qui renvoie un Iterator
avec des informations sur le type, si elles sont présentes. ( Iterator<T>
c'est-à-dire )
Cependant, étant donné qu'il n'y a pas d'information sur le type, l'option Set
retournera un Iterator
qui retournera les valeurs dans le Set
comme Object
et c'est pourquoi l'élément récupéré dans la boucle for-each doit être de type Object
.
Maintenant que le Object
est récupéré à partir de la Set
il doit être transformé en un Integer
manuellement pour effectuer l'ajout :
total += (Integer)o;
Ici, un typecast est effectué à partir d'un Object
à un Integer
. Dans ce cas, nous savons que cela fonctionnera toujours, mais le typage manuel me donne toujours l'impression qu'il s'agit d'un code fragile qui pourrait être endommagé si une modification mineure est apportée ailleurs. (Je pense que chaque typecast est un ClassCastException
en attente de se produire, mais je m'égare...)
Le site Integer
est maintenant décomposé en un int
et autorisé à effectuer l'addition dans le int
variable total
.
J'espère avoir pu illustrer que les nouvelles fonctionnalités de Java 5 sont possibles à utiliser avec du code non générique, mais que ce n'est tout simplement pas aussi propre et direct que d'écrire du code avec des génériques. Et, à mon avis, pour tirer pleinement parti des nouvelles fonctionnalités de Java 5, on devrait se pencher sur les génériques, si au moins, permet des contrôles au moment de la compilation pour empêcher les typescasts invalides de lancer des exceptions au moment de l'exécution.
1 votes
Duplicata de stackoverflow.com/questions/77632/ . Mais la réponse est simple, même si les collections ne font pas partie de votre API, je n'aime pas les castings inutiles, même dans l'implémentation interne.
0 votes
La question est assez similaire, mais je ne pense pas que la réponse acceptée réponde à celle-ci.
1 votes
Vérifiez également stackoverflow.com/questions/520527
4 votes
@MatthewFlaschen bizarre, votre duplicata dirige vers cette question... pépin dans la matrice !
0 votes
@jcollum, je pense que la question originale sur laquelle j'ai posté ce commentaire a été fusionnée avec cette question.
1 votes
Comme @Ijs l'a mentionné -
write code which is applicable to many types with the same underlying behavior
0 votes
Un lien sur les génériques : blogs.msdn.com/kirillosenkov/archive/2008/08/19/ .