是否有任何完全通用的Map.get()版本,即“V get(K key)”

时间:2011-09-14 15:11:43

标签: java generics

由于Map.get()不是完全通用的,我们经常会发现开发人员传递不同类型的对象(以及bug)的情况。当我们开始使用其他团队的工件/服务时,此类案例的频率上升。 What are the reasons why Map.get(Object key) is not (fully) generic解释了为什么get()不是完全通用的。

由于我们实际上没有属于不同类型的两个对象的用例,但“语义上”相同,因此使用Map.get()版本将真正帮助我们在编译时识别这些错误。是否存在可用于生产的任何API?

3 个答案:

答案 0 :(得分:4)

这不是你问题的直接答案,但是有些IDE(至少是IntelliJ)会检查标记集合的可疑用途,这肯定是由它捕获的:

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("hello", 5);

//In IntelliJ, this line gives the warning: 
//Map<String, Integer> may not contain objects of type StringBuilder
System.out.println(map.get(new StringBuilder("hello")));

你提到你试图在编译时捕获这些问题所以我认为值得一提。您可以将它与构建服务器的静态分析工具配对,例如findbugs。

在IntelliJ中,检查称为“可疑收集方法调用”。

编辑(2011/10/18)

在FindBugs中,似乎错误GC_UNRELATED_TYPES应该抓住这个(虽然我没有尝试过测试):

  

GC:通用参数和方法参数之间没有关系

     

对泛型集合方法的这种调用包含一个带有与集合参数不兼容的类的参数(即,参数的类型既不是超类型也不是相应泛型类型参数的子类型)。因此,集合不太可能包含与此处使用的方法参数相同的任何对象。最有可能的是,错误的值被传递给该方法。 (...)

答案 1 :(得分:2)

这是一个提供检查访问的辅助方法:

public static <K, V> V safeGet(Map<? super K, ? extends V> map, K key) {
    return map.get(key);
}

样本用法:

Map<List<String>, Date> map = new HashMap<List<String>, Date>();
// this compiles:
Date date = safeGet(map, Arrays.asList(""));
// this doesn't
Date date2 = safeGet(map, "foo");

答案 2 :(得分:1)