Une caractéristique importante des types paramétriques est la capacité d'écrire des algorithmes polymorphes, c'est-à-dire des algorithmes qui fonctionnent sur une structure de données indépendamment de sa valeur de paramètre, comme Arrays.sort()
.
Avec les génériques, c'est fait avec des types génériques:
<E extends Comparable<E>> void sort(E[]);
Pour être vraiment utiles, les types génériques nécessitent une capture générique, ce qui nécessite la notion de paramètre de type. Rien de tout cela n'était disponible au moment où les tableaux ont été ajoutés à Java, et la création de tableaux de type covariant de référence permettait un moyen beaucoup plus simple d'autoriser des algorithmes polymorphes:
void sort(Comparable[]);
Cependant, cette simplicité a ouvert une faille dans le système de type statique:
String[] strings = {"hello"};
Object[] objects = strings;
objects[0] = 1; // throws ArrayStoreException
nécessitant une vérification à l'exécution de chaque accès en écriture à un tableau de type référence.
En un mot, la nouvelle approche incarnée par les génériques rend le système de type plus complexe, mais aussi plus sûr de type statique, tandis que l'ancienne approche était plus simple et moins sûre de type statique. Les concepteurs du langage ont opté pour une approche plus simple, ayant des choses plus importantes à faire que de fermer une petite faille dans le système de typage qui pose rarement des problèmes. Plus tard, lorsque Java a été établi et que les besoins urgents ont été satisfaits, ils ont eu les ressources pour le faire correctement pour les génériques (mais le changer pour des tableaux aurait cassé les programmes Java existants).