2011-03-05 1 views
6

De acuerdo con los genéricos de Java FAQ http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ302 un parámetro de tipo no puede ser hacia adelante con referencias de esta maneraadelante Referencia del Tipo de parámetro en Java Generics

<A extends B, B> // error 

pero es aceptable tener

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

Estos dos ejemplos se verifican con la última jdk 1.6.0_24.

Mi pregunta es, cuando en la especificación del idioma esto se especifica, implícita o deducible (es decir, si no es cierto, otras cosas pueden explotar). No puedo encontrarlo por ninguna parte.

actualización

En javac7, está permitido. Intuitivamente, el orden de los parámetros de tipo no importa; el sistema de tipo requiere que no haya dependencias cíclicas entre las variables de tipo: <A extends B, B extends A>. Anteriormente, esto puede garantizarse prohibiendo la referencia directa. Aparentemente javac 7 se mejora para relajar el orden, mientras se detectan ciclos independientemente de ordenar.

+0

Parece que esta regla es bien conocida por los chicos de genéricos de java, pero se olvidaron de ponerla en la especificación del idioma. – irreputable

Respuesta

3

No estoy seguro de que esto sea cierto. Miré la Java Language Specification y en § 6.3 hay esta discusión de los alcances de los parámetros de tipo:

El alcance de parámetro de tipo de una interfaz es toda la declaración de la interfaz que incluye la sección parámetro de tipo en sí. Por lo tanto, los parámetros de tipo pueden aparecer como partes de sus propios límites o como límites de otros parámetros de tipo declarados en la misma sección.

El alcance del parámetro de tipo de un método es la declaración completa del método, incluida la sección de parámetros de tipo en sí. Por lo tanto, los parámetros de tipo pueden aparecer como partes de sus propios límites o como límites de otros parámetros de tipo declarados en la misma sección.

El alcance del parámetro de tipo de un constructor es la declaración completa del constructor, incluida la sección de parámetros de tipo en sí. Por lo tanto, los parámetros de tipo pueden aparecer como partes de sus propios límites o como límites de otros parámetros de tipo declarados en la misma sección.

(Mi énfasis).

Esto sugiere que en la declaración

que B es de hecho en su alcance al escribir A extends B.

Además, § 4.4 de la JLS dice, al referirse a la cota en una variable de tipo, que

El límite consiste en ya sea un tipo de variable, o una clase o tipo de interfaz T

lo que sugiere que no solo es B en el alcance en <A extends B, B>, sino que es un límite perfectamente legal en A.

Por último, para colmo, este código se compila en javac:

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

así que estoy bastante seguro de que este es el código de Java perfectamente legal y que el ejemplo que ha enlazado a es el equivocado o se está refiriendo a algo más.

Espero que esto ayude y avíseme si hay algún error en mi razonamiento.

+0

pero no se compila en mi javac1.6 u21 b06. "Referencia directa ilegal" – irreputable

+0

@ irrecuperable- Hmmm, eso es realmente extraño. ¿Estoy malinterpretando las partes relevantes del JLS que he citado? ¿O hay un error en la implementación de 'javac'? – templatetypedef

+0

¿qué versión es tu javac? – irreputable

0

Es completamente legal, digamos más, se puede imaginar que A extiende C, que generalmente se extiende B. Entonces, ¿qué diría usted acerca de cuándo C se extiende B?