在Java中强制转换为泛型类型不会引发ClassCastException吗?
我遇到了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的有用答案。因为我只能接受一个,我接受安杰伊·多伊尔的答案,因为它使我一个解决方案,我觉得是不是 太
糟糕。我认为这是在单行代码中初始化小型Map的更好方法。
/** * 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);
回答:
就像cletus所说的那样,擦除意味着您不能在运行时检查它(并且由于您的转换,您不能在编译时检查它)。
请记住,泛型仅是编译时功能。集合 没有任何通用参数,只有您创建的对该对象的 引用
。这就是为什么如果您需要从原始类型甚至是向下转换集合时会收到很多关于“未检查的强制转换”的警告的Object
原因,因为编译器无法验证对象是否具有正确的泛型类型(如对象本身没有通用类型)。
另外,请记住转换的含义-这是一种告诉编译器“我知道您不一定可以检查类型是否匹配,但是请 ,我知道它们可以。”
当您(不正确地)覆盖类型检查(然后不正确)而导致类型不匹配时,您应该责怪谁?;-)
您的问题似乎出在缺乏异构通用数据结构的周围。我建议您的方法的类型签名应该更像private static<K,V> void
addToMap(Map<K,V> map, List<Pair<K, V>>
vals),但是我不认为这样做真的可以给您带来任何好处。成对列表基本上是一个映射,因此构造typesafe
vals
参数以调用该方法将与直接填充该映射一样多。
如果您 确实确实 希望大致上保持类不变,但是要添加运行时类型安全性,则以下内容可能会给您一些想法:
private static<K,V> void addToMap(Map<K,V> map, Object ... vals, Class<K> keyClass, Class<V> valueClass) { for(int i = 0; i < vals.length; i += 2) {
if (!keyClass.isAssignableFrom(vals[i])) {
throw new ClassCastException("wrong key type: " + vals[i].getClass());
}
if (!valueClass.isAssignableFrom(vals[i+1])) {
throw new ClassCastException("wrong value type: " + vals[i+1].getClass());
}
map.put((K)vals[i], (V)vals[i+1]); //Never throws ClassCastException!
}
}
以上是 在Java中强制转换为泛型类型不会引发ClassCastException吗? 的全部内容, 来源链接: utcz.com/qa/400935.html