下面的代码显示我可以在Map中插入不兼容的类型,但是当我无法从中检索元素时.在下面的例子中,我可以将两个整数放入Map中,但如果我取消注释最后两行,我将得到ClassCastException.这是JDK的错误,或者我错过了什么,因为我记得Java通用保证我们不能将不兼容的类型插入到泛型集合类中.
公共类HelloWorld {
private static class MapResultExtractor<K, V> {
public Map<K, V> extract(Iterator<List<Object>> iter)
throws IOException {
Map<K, V> map = new HashMap<K, V>();
while (iter.hasNext()) {
List<Object> tuple = iter.next();
K key = (K) (tuple.get(0) == null ? null : tuple.get(0));
V value = (V) (tuple.get(1) == null ? null : tuple.get(1));
map.put(key, value);
}
return map;
}
}
public static void main(String[] args) throws IOException {
MapResultExtractor<String, Integer> extractor = new MapResultExtractor<String, Integer>();
List<Object> subList = new ArrayList<Object>();
subList.add(1);
subList.add(2);
List<List<Object>> list = new ArrayList<List<Object>>();
list.add(subList);
Map<String, Integer> map = extractor.extract(list.iterator());
for (Map.Entry<String, Integer> entry : map.entrySet()) {
// System.out.println(entry.getKey().getClass() + "\t"
// + entry.getValue().getClass());
}
}
Run Code Online (Sandbox Code Playgroud)
}
Vic*_*kin 10
编译器无法在这里查看
K key = (K) (tuple.get(0) == null ? null : tuple.get(0));
Run Code Online (Sandbox Code Playgroud)
你真的传递了类型的对象K(你真的传递了Integer而不是String).所以编译器信任你.
在运行时级别有类型擦除,所以当该行执行时,没有K,而是有
Object key = (tuple.get(0) == null ? null : tuple.get(0));
Run Code Online (Sandbox Code Playgroud)
只有这样你才真正尝试使用Integer值而不是String in println,运行时可以检测到类型不匹配.
解?使用Iterator<List<K>>而不是Iterator<List<Object>>作为你的extract()方法的参数(那么,在当前版本中,你将被迫返回Map<K, K>而不是Map<K, V>,这就是重点).
同样,代码的问题在于您强制将Integer视为对象(这是合法的)并强制将对象转换为类型K(在编译期间始终是合法的,并且在运行时并不总是正确的).