Al investigar otra pregunta , me topé con este comportamiento intrigante del compilador Sun-Oracle 1.8.0_112 (no lo he probado con otros):
import java.util.List; interface Alpha<T> { List<Integer> intList(); } interface Beta { List<Integer> intList(); } class Main { public static void main(String[] args) { Alpha rawAlpha = null; Alpha<Character> charAlpha = null; Alpha<?> qmAlpha = null; Beta beta = null; for (Integer i : charAlpha.intList()) {} for (Integer i : qmAlpha.intList()) {} for (Integer i : beta.intList()) {} for (Integer i : rawAlpha.intList()) {} } }El compilador solo falla en el último bucle for:
error: incompatible types: Object cannot be converted to Integer for (Integer i : rawAlpha.intList()) {} ^ 1 error Entonces, a pesar de que el tipo de lista de devolución intList() List<Integer> en Alpha no depende del parámetro de tipo T , parece que <Integer> se borra en el momento de la compilación.
Tenga en cuenta que si declaramos una interfaz Beta no genérica que sería, en teoría, equivalente a hacer referencia a la Alpha sin procesar, no hay problema.
¿Es este el comportamiento esperado? ¿alguien puede señalar el párrafo sobre la especificación del idioma que cubriría este punto? Si esto no es un error, al menos parece bastante anti-intuitivo y no productivo; tal vez se hace en aras de la retrocomparabilidad?.
El bit JLS que dice esto (un poco confuso) está en JLS 4.8 :
El tipo de un constructor (§8.8), método de instancia (§8.4, §9.4) o campo no estático (§8.3) de un tipo C sin formato que no se hereda de sus superclases o superinterfaces es el tipo sin formato que corresponde a la supresión de su tipo en la declaración genérica correspondiente a C.
Entonces, dado que rawAlpha es un tipo sin formato, el tipo de rawAlpha.intList es el borrado de List<Integer> intList() . Ese borrado es List intList() .
En cuanto a por qué, no tengo una cita a mano, pero los tipos sin procesar solo están realmente en Java para compatibilidad con versiones anteriores. Eso significa que solo necesitan funcionar tan bien como antes de los genéricos; lo que está pidiendo es un código que funcione un poco mejor que antes. No es irrazonable, pero no es lo que decidieron. :-)