Sto cercando di capire perché questo codice ha un avviso di cast non controllato. I primi due calchi hanno alcun avvertimento, ma il terzo fa:Un cast non controllato nella classe generica che implementa Mappa <String, V>
class StringMap<V> extends HashMap<String, V> {
}
class StringToIntegerMap extends HashMap<String, Integer> {
}
Map<?, ?> map1 = new StringToIntegerMap();
if (map1 instanceof StringToIntegerMap) {
StringToIntegerMap stringMap1 = (StringToIntegerMap)map1; //no unchecked cast warning
}
Map<String, Integer> map2 = new StringMap<>();
if (map2 instanceof StringMap) {
StringMap<Integer> stringMap2 = (StringMap<Integer>)map2; //no unchecked cast warning
}
Map<?, Integer> map3 = new StringMap<>();
if (map3 instanceof StringMap) {
StringMap<Integer> stringMap3 = (StringMap<Integer>)map3; //unchecked cast warning
}
Questa è la piena avvertimento per il stringMap3
Cast:
Tipo di sicurezza: Non selezionata lanciato dalla
Map<capture#3-of ?,Integer>
aStringMap<Integer>
Tuttavia, la dichiarazione di classe StringMap
specifica il primo parametro di tipo di Map
(ad esempio, String
) ed entrambi map3
e il cast StringMap<Integer>
utilizzano lo stesso tipo per il secondo parametro di tipo di Map
(ad esempio, Integer
). Da quanto ho capito, fino a quando il cast non getta ClassCastException
(e non dovrebbe, dal momento che c'è un controllo instanceof
), stringMap3
sarebbe un valido Map<String, Integer>
.
Si tratta di una limitazione del compilatore Java? Oppure esiste uno scenario in cui i metodi di chiamata di map3 o stringMap3 con determinati argomenti possono causare un inaspettato ClassCastException
se l'avviso viene ignorato?
Questa era la conclusione a cui stavo venendo dopo aver letto la risposta di @ pifta e varie sezioni nel JLS. Suppongo che il JLS possa essere aggiornato per aggiungere migliori regole di casting tra due tipi parametrizzati in cui le rispettive classi generiche usano un diverso numero di parametri di tipo, ma non saprei quanto sia fattibile questo o gli effetti collaterali. Questa domanda sembra essere correlata, a meno che non mi sbagli: [Trasmissione a sottotipi generici di una classe generica] (// stackoverflow.com/questions/17883536/casting-to-generic-subtypes-of-a-generic-class) . – blurredd