2011-03-05 3 views
6

Selon Java Generics FAQ http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 un paramètre de type ne peut pas être tournées vers l'référencés de cette manièreForward Référence du type de paramètre en Java Generics

<A extends B, B> // error 

mais il est correct d'avoir

<A extends List<B>, B> // ok 

Ces deux exemples sont vérifiés avec la dernière jdk 1.6.0_24. Ma question est, où dans la spécification de la langue cela est spécifié, implicite, ou déductible (c'est-à-dire si elle est fausse, d'autres choses peuvent exploser). Je ne peux le trouver nul part.

Mise à jour

En javac7, il est autorisé. Intuitivement, l'ordre des paramètres de type n'a pas d'importance; le système de type requiert qu'il n'y ait pas de dépendances cycliques parmi les variables de type: <A extends B, B extends A>. Auparavant, cela peut être garanti en interdisant la référence vers l'avant. Apparemment javac 7 est amélioré pour relâcher la commande, tout en détectant les cycles indépendamment de la commande.

+0

Il semble donc que cette règle soit bien connue par les génériques java, mais ils ont oublié de la mettre dans la spécification du langage. – irreputable

Répondre

3

Je ne suis pas sûr que ce soit vrai. Je regardais la Java Language Specification et § 6.3, il y a cette discussion des champs d'application des paramètres de type:

La portée du paramètre de type d'une interface est toute déclaration de l'interface, y compris la section des paramètres de type lui-même. Par conséquent, les paramètres de type peuvent apparaître en tant que parties de leurs propres limites ou en tant que limites d'autres paramètres de type déclarés dans la même section.

La portée d'un paramètre de type de méthode est la déclaration complète de la méthode, y compris la section de paramètre de type elle-même. Par conséquent, les paramètres de type peuvent apparaître en tant que parties de leurs propres limites ou en tant que limites d'autres paramètres de type déclarés dans la même section.

La portée d'un paramètre de type constructeur est la déclaration entière du constructeur, y compris la section de paramètre de type elle-même. Par conséquent, les paramètres de type peuvent apparaître en tant que parties de leurs propres limites ou en tant que limites d'autres paramètres de type déclarés dans la même section.

(Je souligne).

Cela donne à penser que, dans la déclaration

que B est en effet portée lors de l'écriture A extends B.

En outre, § 4.4 du JLS dit, en se référant à la limite d'une variable de type, qui

La limite est constituée soit une variable de type , ou un type de classe ou de l'interface T

Ce qui suggère que est non seulement B dans la portée <A extends B, B>, mais que c'est une limite parfaitement légale sur A.

Enfin, pour couronner le tout, ce code compile en javac:

public class Test { 
    public static <A extends B, B> A test(B obj) { 
     return null; 
    } 
} 

Je suis assez sûr que cela est parfaitement code juridique Java et que l'exemple que vous avez lié à est soit faux ou fait référence à autre chose.

J'espère que cela aide, et laissez-moi savoir s'il y a une faille dans mon raisonnement!

+0

mais il ne compile pas dans mon javac1.6 u21 b06. "référence avancée illégale" – irreputable

+0

@ irreputable- Hmmm, c'est vraiment bizarre. Suis-je en train d'interpréter les parties pertinentes de la JLS que j'ai citées? Ou y a-t-il un bug dans votre implémentation 'javac'? – templatetypedef

+0

Quelle est la version de votre javac? – irreputable

0

Il est tout à fait légal, disons plus, vous pouvez imaginer que A étend C qui étend généralement B. Alors, que diriez-vous de quand C étend B?