Cette règle vise à éviter les conflits dans le code hérité qui utilise toujours des types bruts.
Voici une illustration de la raison pour laquelle cela n'a pas été autorisé, tirée du JLS. Supposons que, avant l'introduction des génériques en Java, j'ai écrit du code comme celui-ci:
class CollectionConverter {
List toList(Collection c) {...}
}
Vous prolongez ma classe, comme ceci:
class Overrider extends CollectionConverter{
List toList(Collection c) {...}
}
Après l'introduction des génériques, j'ai décidé de mettre à jour ma bibliothèque.
class CollectionConverter {
<T> List<T> toList(Collection<T> c) {...}
}
Vous n'êtes pas prêt à faire des mises à jour, alors vous laissez votre Overrider
classe tranquille. Afin de remplacer correctement la toList()
méthode, les concepteurs de langage ont décidé qu'un type brut était "équivalent à la substitution" à tout type généré. Cela signifie que bien que la signature de votre méthode ne soit plus formellement égale à la signature de ma superclasse, votre méthode est toujours prioritaire.
Maintenant, le temps passe et vous décidez que vous êtes prêt à mettre à jour votre classe. Mais vous bousiller un peu, et au lieu de modifier la toList()
méthode brute existante , vous ajoutez une nouvelle méthode comme celle-ci:
class Overrider extends CollectionConverter {
@Override
List toList(Collection c) {...}
@Override
<T> List<T> toList(Collection<T> c) {...}
}
En raison de l'équivalence de remplacement des types bruts, les deux méthodes sont sous une forme valide pour remplacer la toList(Collection<T>)
méthode. Mais bien sûr, le compilateur doit résoudre une seule méthode. Pour éliminer cette ambiguïté, les classes ne sont pas autorisées à avoir plusieurs méthodes équivalentes à la substitution, c'est-à-dire plusieurs méthodes avec les mêmes types de paramètres après l'effacement.
La clé est qu'il s'agit d'une règle de langage conçue pour maintenir la compatibilité avec l'ancien code à l'aide de types bruts. Ce n'est pas une limitation requise par l'effacement des paramètres de type; étant donné que la résolution de méthode se produit au moment de la compilation, l'ajout de types génériques à l'identificateur de méthode aurait été suffisant.