Это надуманный пример, иллюстрирующий проблему. Я знаю, что есть способы обойти , которые не генерируют предупреждения компилятора, и вы также можете отключить предупреждение. Мне интересно, если это возможно без каких-либо из этих уловок.
Учитывая этот код:
1 public static void main(String[] args) {
2 Map<String,String> map = null;
3
4 HashMap<String,String> hmap;
5
6 if(map instanceof HashMap)
7 hmap = (HashMap<String,String>)map;
8 else
9 hmap = new HashMap<String,String>(map);
10
11 map = (Map<String,String>)hmap.clone();
12
13 Object o = hmap.clone();
14 if(o instanceof Map<?,?>)
15 map = (Map<String,String>)o;
16 }
Код в обеих строках 11 и 15 генерирует компиляторпредупреждение:
Unchecked cast from Object to Map<String,String>
Строка 11 немного понятна: Object.clone()
возвращает Object
, и проверки перед проверкой не было instanceof
. Программист знает , что клоном будет Map<String,String>
, но компилятор не может этого доказать.
Строка 15, однако, озадачивает меня. Обычно проверка типа переменной с помощью instanceof
и последующее приведение к ней не генерируют такого предупреждения. Действительно, замена кода на непараметрические классы, подобные этому, не вызовет предупреждений ни в одной из следующих строк кода:
static class A {}
static class B extends A implements Cloneable {
public Object clone() { return null; }
}
public static void main(String[] args) {
A a = null;
B b;
if(a instanceof B)
b = (B)a;
else
b = new B();
a = (A)b.clone();
Object o = b.clone();
if(o instanceof A)
a = (A)o;
}
Назад к исходному коду (со ссылками Map<String,String>
), даже добавляяэта неуклюжая конструкция до конца кода генерирует похожее предупреждение:
map = (Map<String,String>)hmap.getClass().cast(o);
На этот раз предупреждение Unchecked cast from capture#11-of ? extends HashMap to Map<String,String>
. Попытка написать:
map = HashMap<String,String>.class.cast(o);
Генерирует компилятор error , потому что он не может понять, что HashMap<String,String>.class
является ссылкой на статический класс так же, как, например, HashMap.class
, поэтомумы должны использовать ссылку «правильного» типа для вызова Class.cast
.
Это то, что Java просто не может сделать?