The following code shows that I can insert uncompatible type into Map, but when I can not retrieve element from it. In the following example, I can put two integers into Map, but if I uncomment the last two lines, I will get ClassCastException.
Is this bug of JDK, or I miss something, as I remember Java generic guarantees taht we can not insert uncompatible type into generics collection class.
public class 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());
}
}
}
Compiler can’t check here
that you really passed object of type
K(and you really passed Integer instead of String).So compiler trusts you.
On runtime level there’s type-erasure, so when that line executes, there’s no
K, instead there’sOnly then you actually try to use Integer value instead of String in
println, runtime can detect type mismatch.Solution? Use
Iterator<List<K>>instead ofIterator<List<Object>>as argument to yourextract()method (well, then, in current version, you’ll be forced to returnMap<K, K>instead ofMap<K, V>, and that’s the point).Again, the problem with code is that you forced Integer to be treated as Object (which is legal) and forcibly casted Object to type K (which is always legal during compilation, and not always correct during runtime).