返回通用Map.entrySet()的类型

时间:2016-04-21 20:11:12

标签: java generics

Map.entrySet()声明为:

Set<Map.Entry<K, V>> entrySet();

在某处我定义了一个这样的变量:

Map<? extends Number, String> wildCardMap = new HashMap<>();

现在,我假设类型参数K ?扩展数字,我可以这样做:

Set<Map.Entry<? extends Number, String>> entries = wildCardMap.entrySet();

但这会产生编译错误,我必须写:

Set<? extends Map.Entry<? extends Number, String>> entries = wildCardMap.entrySet();

有人可以在Map.Entry之前解释为什么需要通配符吗?

1 个答案:

答案 0 :(得分:1)

通配符? extends Number表示扩展Number的某些特定(我们未知)类型。因此,让我们尝试一种可能的类型,Integer,看看会发生什么:

Map<Integer, String> wildCardMap;

// doesn't compile
Set<Map.Entry<? extends Number, String>> entries = wildCardMap.entrySet();

为什么呢?由于wildCardMap.entrySet()会返回Set<Map.Entry<Integer, String>>,而Set<Map.Entry<? extends Number, String>>不是Set<Map.Entry<Integer, String>>的子类型。

泛型是不变的,类型参数必须完全匹配,除非类型参数是通配符。更深层次的通配符不算数(它只是该类型的一部分)。 Set<Map.Entry<? extends Number, String>>不是Map.Entry<Integer, String>的子类型,即使Map.Entry<? extends Number, String>List<String>的子类型,就像List<Object>不是String的子类型一样即使ObjectInputStream的子类型。