Cette limitation est une partie de la syntaxe de la langue, pas le Java runtime lui-même. Essentiellement, cette règle vise à éviter les conflits d'héritage de code qui utilise toujours cru types.
Un compilateur comme javac
refusent ce type de surcharge, mais si vous créez une classe par d'autres moyens (la rédaction de votre propre compilateur, ou à l'aide d'un byte-code de l'ingénierie de la bibliothèque comme ASM) avec des signatures qui ne diffèrent que par le type de paramètres, l' javac
compilateur va résoudre les appels à la méthode correcte de votre classe.
Voici une illustration de pourquoi cela n'a pas été autorisé, établi à partir de la JLS. Supposons que, avant de génériques ont été introduites pour Java, j'ai écrit un code comme ceci:
class CollectionConverter {
List toList(Collection c) {...}
}
Vous étendre ma classe, comme ceci:
class Overrider extends CollectionConverter{
List toList(Collection c) {...}
}
Après l'introduction de 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 toutes les mises à jour, de sorte que vous laissez votre Overrider
classe seul. Afin de remplacer l' toList()
méthode, la langue de créateurs ont décidé qu'une crue de type a "remplacer l'équivalent de" à tout generified type. Cela signifie que, bien que votre signature de la méthode n'est plus formellement égal à mon super-classe " signature, votre méthode encore des remplacements.
Maintenant, le temps passe et que vous décidez que vous êtes prêt à mettre à jour votre classe. Mais tu vis un peu, et au lieu de modifier l'existant, raw toList()
méthode, vous ajoutez une nouvelle méthode comme ceci:
class Overrider extends CollectionConverter {
@Override
List toList(Collection c) {...}
@Override
<T> List<T> toList(Collection<T> c) {...}
}
En raison de la substitution de l'équivalence de raw types, les deux méthodes sont dans une forme valide pour remplacer l' toList(Collection<T>)
méthode. Mais bien sûr, le compilateur a besoin de résoudre une seule méthode. Pour éliminer cette ambiguïté, les classes ne sont pas autorisés à avoir plusieurs méthodes qui sont override-équivalent—qui est, plusieurs méthodes avec les mêmes types de paramètres après l'effacement.
La clé, c'est que c'est une langue de la règle conçu pour permettre la poursuite de l'utilisation de matières premières, pas une limitation résultant de l'effacement des paramètres de type.
Si vous éliminez l'héritage de code (par exemple, en utilisant votre propre, non-strictement-langage Java), ce type de surcharge fonctionne parfaitement. Parce que la méthode de résolution se produit au moment de la compilation, avant l'effacement, le type de la réification n'est pas nécessaire pour faire ce travail.