Java泛型和向上转换

时间:2011-08-22 05:39:41

标签: java generics type-conversion

有人能解释一下为什么会这样吗

Map<String, List<String>> foo = new HashMap<String, LinkedList<String>>();

生成类型不匹配错误?

  

类型不匹配:无法从HashMap&lt;转换串,链表&LT;串GT;&GT;到Iterators.Map&lt;串,列表与LT;串GT;&GT;

Hashmap实现Map接口,LinkedList实现List接口。而且,这个

List<String> foo = new LinkedList<String>();

工程...

由于

4 个答案:

答案 0 :(得分:6)

由于Map<String, List<String>>允许您put ArrayList<String>,但这样做会违反HashMap<String, LinkedList<String>>的类型完整性。

HashMap声明为HashMap<String, List<String>>或将变量声明为Map<String, LinkedList<String>>Map<String, ? extends List<String>>

修改

更直接的问题是您导入了错误的Map类(称为Iterators.Map),或者您在同一个包中有另一个类(或内部类)称为Map作为这个代码。您想要导入java.util.Map

答案 1 :(得分:3)

在Java中,泛型不保留子类型协方差。因此,如果B是A的子类型,则Gen(B)可能不是Gen(A)的子类型,其中Gen是某种形式的通用用法。

具体而言,如果LinkedListList的子类型,则并不意味着Map<String,LinkedList>Map<String,List>的子类型。正如其他帖子所建议的那样,您必须在List类型参数中使用HashMap作为您的类型。

答案 2 :(得分:1)

修复此问题如下:

Map<String, List<String>> result = new HashMap<String, List<String>>();

请注意,我已将LinkedList更改为作业右侧的List

LinkedList实现List是对的。但我认为对此错误的解释不是在List的定义中,而是在接口Map<K,V>的定义中。

表达式的左侧表示您要创建字符串和列表的映射,即V由List“替换”。右侧使用LinkedList。虽然LinkedList实现了List但它不起作用,因为Map的定义不像Map<K, V extends List>,所以编译器需要完全匹配。

我不确定我的描述是否足够严格,但无论如何这是通往正确的泛型的方法。实际上,当您创建列表地图时,您并不关心List的实现,因此请说HashMap<String, List<String>>。仅当您创建List关注其实现的实例时。这将允许您在未经修改其他代码的情况下更改实现。

答案 3 :(得分:0)

请使用HashMap接口:

Map<String, List<String>> foo = new HashMap<String, List<String>>();

List<String> bar = new LinkedList<String>();

foo.put("barkey", bar);