Я столкнулся с странным поведением Java, которое кажется ошибкой. Это? Приведение объекта к общему типу (например, K
) не бросает ClassCastException
, даже если объект не является экземпляром K
. Вот пример:
import java.util.*;
public final class Test {
private static<K,V> void addToMap(Map<K,V> map, Object ... vals) {
for(int i = 0; i < vals.length; i += 2)
map.put((K)vals[i], (V)vals[i+1]); //Never throws ClassCastException!
}
public static void main(String[] args) {
Map<String,Integer> m = new HashMap<String,Integer>();
addToMap(m, "hello", "world"); //No exception
System.out.println(m.get("hello")); //Prints "world", which is NOT an Integer!!
}
}
Обновление: благодаря cletus и Andrzej Doyle за ваши полезные ответы. Поскольку я могу только принять его, я принимаю ответ Andrzej Doyle, потому что это привело меня к решению, которое, я думаю, не так уж плохо. Я думаю, что это немного лучший способ инициализации небольшой карты в однострочном пространстве.
/**
* Creates a map with given keys/values.
*
* @param keysVals Must be a list of alternating key, value, key, value, etc.
* @throws ClassCastException if provided keys/values are not the proper class.
* @throws IllegalArgumentException if keysVals has odd length (more keys than values).
*/
public static<K,V> Map<K,V> build(Class<K> keyClass, Class<V> valClass, Object ... keysVals)
{
if(keysVals.length % 2 != 0)
throw new IllegalArgumentException("Number of keys is greater than number of values.");
Map<K,V> map = new HashMap<K,V>();
for(int i = 0; i < keysVals.length; i += 2)
map.put(keyClass.cast(keysVals[i]), valClass.cast(keysVals[i+1]));
return map;
}
И тогда вы называете это следующим образом:
Map<String,Number> m = MapBuilder.build(String.class, Number.class, "L", 11, "W", 17, "H", 0.001);