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之前解释为什么需要通配符吗?
答案 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
的子类型一样即使Object
是InputStream
的子类型。