public class HttpQueryMap extends HashMap<String,String> { ... @Override public void putAll(Map<? extends String,? extends String> m) { ... Iterator<Map.Entry<String,String>> iterator = m.entrySet().iterator(); ... } ... }
我收到编译时错误
incompatible types required: Iterator<Entry<String,String>> found: Iterator<Entry<CAP#1,CAP#2>> where CAP#1,CAP#2 are fresh type-variables: CAP#1 extends String from capture of ? extends String CAP#2 extends String from capture of ? extends String
下一个解决方案可以完成这项工作,但实际上很丑陋:
public class HttpQueryMap extends HashMap<String,? extends String> m) { ... Map<String,String> m_str=new HashMap<String,String>(); m_str.putAll(m); Iterator<Map.Entry<String,String>> iterator = m_str.entrySet().iterator(); ... } ... }
据我所知,问题是Iterator中使用的类型变量String< Map.Entry< String,String>>不扩展Map<?声明中使用的String(本身)扩展字符串,? extends String>米
解决方法
最简单的方法是使用for-each循环.即使在这种情况下,您也需要使用与给定映射中相同的通配符对Entry进行参数化.原因是Entry<?扩展字符串,? extends String>不是Entry< String,String>的子类型. String是最终类的事实在这里是无关紧要的,因为编译器不知道这一点.
for (Entry<? extends String,? extends String> entry : m.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); }
有了Iterator
如果你真的需要一个Iterator,那么编译的语法有点莫名其妙:
Iterator<? extends Entry<? extends String,? extends String>> iterator = m.entrySet().iterator(); while (iterator.hasNext()) { Entry<? extends String,? extends String> entry = iterator.next(); String key = entry.getKey(); String value = entry.getValue(); }
我最初期望迭代器只是Iterator类型< Entry<?扩展字符串,? extends String>>,它最初看起来是在Set< Entry<?上调用的iterator()方法的返回类型.扩展字符串,? extends String>>这反过来似乎是在Map<?上调用的entrySet()的返回类型扩展字符串,? extends String>.
但是,它比这复杂一点.我在这里找到了一个可能的答案:
有趣的是这个:
The problem is that the
entrySet()
method is returning a
Set<Map.Entry<capture-of ? extends K,capture-of ? extends V>>
,
which is incompatible with the typeSet<Map.Entry<? extends K,? extends V>>
.
It’s easier to describe why if I drop theextends K
andextends V
part.
So we haveSet<Map.Entry<?,?>
andSet<Map.Entry<capture-of ?,capture-of ?>>
.The first one,
Set<Map.Entry<?,?>>
is a set of Map.Entries of different
types – ie it is a heterogeneous collection. It could contain a
Map.Entry<Long,Date>
and aMap.Entry<String,ResultSet>>
and any other
pair of types,all in the same set.On the other hand,
Set<Map.Entry<capture-of ?,capture-of ?>>
is a homogenous
collection of the same (albeit unknown) pair of types. Eg it might be a
Set<Map.Entry<Long,Date>>
,so all of the entries in the set MUST be
Map.Entry<Long,Date>
.