Map.entrySet() 声明为:
Set<Map.Entry<K, V>> entrySet();
我在某个地方定义了一个这样的变量:
Map<? extends Number, String> wildCardMap = new HashMap<>();
现在,我假设类型参数 K 是 ?扩展 Number,我可以这样做:
Set<Map.Entry<? extends Number, String>> entries = wildCardMap.entrySet();
但这会产生编译错误,我必须写:
Set<? extends Map.Entry<? extends Number, String>> entries = wildCardMap.entrySet();
有人可以解释一下为什么在 Map.Entry 之前需要通配符吗?
最佳答案
通配符? 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
的子类型.
关于java - 通用 Map.entrySet() 的返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36779497/