Esto es un error bastante común:
ForEachLoop f = new ForEachLoop();
debería ser
ForEachLoop<Something> f = new ForEachLoop<Something>();
Si se utiliza el tipo de prima (que no debe) el compilador borrará toda la información genérica para esa instancia, incluso si no es el parámetro de tipo T, para que sea compatible con código pre 1.5.
Solo use tipos sin formato si está escribiendo para Java 1.4 o menos, en cuyo caso no debería tener genéricos de ningún tipo. En el nivel de bytecode, el método devuelve una colección (en bruto) después de borrar el tipo. Normalmente, si la instancia tiene el conjunto de tipos genérico, cuando intenta hacer get
en la colección, el compilador usará la información genérica para decidir que debe devolver una Cadena, y luego en el nivel de código de bytes arrojará automáticamente el Objeto que recibe de la Colección a Cadena (ya que se garantiza que es una Cadena). Pero si usa el tipo sin formato, el compilador ignorará toda la información genérica y ya no volverá a enviar el objeto automáticamente.
Editar: En la sección de Tipos primas hay estas cosas:
Otra implicación de las reglas anteriores es que una clase interna genérica de un crudo tipo puede por sí mismo sólo se puede utilizar como una prima tipo :
class Outer<T>{
class Inner<S> {
S s;
}
}
no es posible acceder a la interior como tipo parcialmente en bruto (un tipo "raro")
Outer.Inner<Double> x = null; // illegal
Double d = x.s;
porque la propia Outer es crudo, por lo que son todas sus clases internas, incluyendo interior, y por lo que no es posible pasar cualquier parámetros de tipo a ella.
El uso de tipos sin procesar solo se permite como una concesión a la compatibilidad del código heredado . Se desaconseja encarecidamente el uso de tipos sin procesar en el código escrito después de la introducción de la geniticidad en el lenguaje de programación de Java. Es es posible que las versiones futuras de el lenguaje de programación Java no permitan el uso de tipos sin procesar.
Es un error en tiempo de compilación intentar utilizar un tipo de miembro de tipo parametrizado como tipo sin formato.
Esto significa que la prohibición de "raros" tipos extiende al caso en que el tipo de clasificación se parametriza, pero que intenta utilizar la clase interna como tipo prima:
Outer<Integer>.Inner x = null; // illegal
Este es lo opuesto al caso en que se discutió anteriormente. No hay ninguna justificación práctica para este tipo medio horneado . En el código heredado, no se utilizan parámetros de tipo . En el código no heredado, debemos usar los tipos genéricos correctamente y pasar todos los parámetros de tipo real requeridos.
Observe que la clase Inner tiene su propio parámetro de tipo independiente de la de la clase Externa, y todavía se borra. Básicamente no quieren que mezclemos tipos crudos y genéricos en la misma instancia, ya que no tiene sentido en ninguna versión (en pre 1.5, la parte genérica será un error, en 1.5+ no se recomienda el tipo sin formato, y incluso puede ser removido de las versiones futuras)
Luego está también esto:
El tipo de un constructor (§8.8), método de instancia (§8.8, §9.4), o campo no estático (§8.3) M de un bruto tipo C que no se hereda de sus superclases o superinterfaces es el borrado de su tipo en la declaración genérica correspondiente a C. El tipo de un miembro estático de un tipo de prima C es el mismo que su tipo en la declaración genérica correspondiente a C.
Es un error de tiempo de compilación para pasar parámetros de tipo real a un miembro de tipo no estático de un tipo sin formato que no es heredado de sus superclases o superinterfaces .
que dice que los constructores, los métodos de instancia y los campos no estáticos se tratarán como sin procesar en una instancia sin formato. Los miembros estáticos se tratarán como genéricos de todos modos, ya que no requieren el acceso de una instancia.
suena interesante y lógica. ¿Podría indicarme la especificación java de que "el compilador borrará toda la información genérica incluso si no es el parámetro de tipo T"? –
Agregué algunos fragmentos del JLS y mi comprensión (quizás limitada) de ellos. –
Intentaré absorber tu respuesta, pero me llevará un tiempo. Gracias –