A nivel de código de bytes del método tendrá un descriptor que se limita a decir, hay un método con el nombre de getHashMap, que no tiene argumentos y devuelve un mapa (no hay genéricos).
Luego, cuando el compilador está analizando la línea Map<String, Map<Long, List<String>>> map = getHashMap();
, y dirá, bien, tengo que tener una variable con un tipo declarado de Map<String, Map<Long, List<String>>>
, pero para realmente obtener la instancia Tengo que llamar a un método. En este punto, es tarea del compilador comprobar si el tipo de devolución del método coincide con el tipo declarado de la variable a la que se asigna ese resultado. Por lo tanto, comprueba si String
coincide con K
, y si Map<Long, List<String>>
coincide con V, lo que hacen, por lo que considera que la asignación es segura y genera el bytecode que básicamente utiliza una variable de mapa (no genéricos).
Si hubiera declarado su método:
static <K extends Number,V> Map<K,V> getHashMap()
{
return new HashMap<K, V>();
}
al analizar la asignación, el compilador vería que no coincide con String
K extends Number
, arrojaría un error de compilación, y no va a crear el código de bytes de esa asignación.
¿Puede explicarme un poco? – Emil
@Emil ¿Sobre qué? –
@Tom: ¿Qué quiere decir con que javac inferirá el tipo? ¿Puede explicar cómo funciona esto en los pasos? – Emil