Я пытаюсь понять, почему этот код имеет предупреждение о непроверенном приведении. Первые два приведения не имеют предупреждения, но третье имеет:
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
}
Это полное предупреждение для приведения stringMap3
:
Безопасность типов: непроверенное приведение от
Map<capture#3-of ?,Integer>
кStringMap<Integer>
Однако в объявлении класса StringMap
указан параметр первого типа Map
(т. е. String
), а map3
и приведение StringMap<Integer>
используют один и тот же тип для параметра второго типа Map
(т. е. Integer
). Насколько я понимаю, пока приведение не выдает ClassCastException
(а этого не должно быть, поскольку есть проверка instanceof
), stringMap3
будет действительным Map<String, Integer>
.
Является ли это ограничением компилятора Java? Или есть сценарий, в котором вызов методов map3 или stringMap3 с определенными аргументами может привести к неожиданному ClassCastException
, если предупреждение будет проигнорировано?