36 votes

Effacement de type, surcharge et génériques

Quelqu'un peut-il m'expliquer pourquoi

@Override
public void fooMethod(Class<?> c)

ne supplante pas

public void fooMethod(Class c)

et me donne les erreurs suivantes à la place :

 - Name clash: The method fooMethod(Class<?>) 
of type SubClass has the same erasure as fooMethod(Class) of 
type SuperClass but  does not override it

 - The method fooMethod(Class<?>) of type 
SubClass must override a superclass method

?

Edit : " java -version " dit Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_16-b06-284). Quant à l'extrait de code, il se trouve déjà au-dessus, à peu près ; ce qui précède prolonge ce qui suit.

47voto

eljenso Points 7690

La signature de fooMethod(Class<?>) est la même que la signature de fooMethod(Class) après l'effacement, puisque l'effacement de Class<?> est simplement Class ( JLS 4.6 ). Par conséquent, fooMethod(Class) est une subsignature de la fooMethod(Class<?>) mais pas l'inverse ( JLS 8.4.2 ).

Pour remplacer une méthode d'instance par une autre, il faut que la méthode de remplacement soit une sous-signature de la méthode de remplacement ( JLS 8.4.8.1 ). Ce n'est manifestement pas le cas ici.

Maintenant que nous avons établi le fait que la méthode de votre sous-classe ne surcharge pas la méthode de la super-classe selon le JLS, examinons les implications au niveau de l'exécution lorsque l'effacement de type a eu lieu. Nous avons maintenant deux méthodes qui ont exactement la même apparence (même nom, mêmes types de paramètres) mais qui ne sont pas prioritaires l'une par rapport à l'autre. Si elles ne se substituent pas l'une à l'autre, elles doivent être toutes deux disponibles sur le sous-type en tant que méthodes distinctes, mais elles ont des signatures d'exécution identiques : il y a conflit. Java doit donc l'interdire.

Remplacement des types de paramètres génériques par des types de paramètres bruts es autorisé parce que les types bruts existent juste pour cette raison : ils sont un mécanisme pratique avec des règles de type spécifiques non solides pour permettre l'interaction avec le code hérité. Ainsi, le système de types décidera ici que la méthode de la sous-classe fait remplacent celle de la superclasse, ils sont identique après l'effacement du type et nous ne pouvons jamais avoir de conflit. En conséquence, les bibliothèques peuvent être générées indépendamment du code non-générique existant.

-3voto

Staale Points 8795

Parce que Class<?> est plus spécifique que le simple Class .

Par exemple, foo(Class<List>) ne peut pas passer outre foo(Class<Collection>) . J'ai oublié le terme, mais les types avec génériques seront toujours différents de ceux sans génériques.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X