2010-12-16 25 views
3

不兼容的通用通配符捕获下面的代码片段

package test; 

import java.util.Collection; 
import java.util.Iterator; 
import java.util.Map; 

public class WildcardsTest<K, V> { 
    private Iterator<Map.Entry<K, ? extends Collection<V>>> iterator; 
    public WildcardsTest(Map<K, ? extends Collection<V>> map) { 
     iterator = map.entrySet().iterator(); 
     /* Type mismatch: cannot convert from 
      Iterator<Map.Entry<K,capture#1-of ? extends Collection<V>>> to 
      Iterator<Map.Entry<K,? extends Collection<V>>> */ 
    } 
} 

的分配不正确,虽然类型似乎完全匹配。

我通过指定集合的​​类型,另一个泛型参数,这样的设计了一个肮脏的解决方法:

public class WildcardsTest<K, V, C extends Collection<V>> { 
    private Iterator<Map.Entry<K, C>> iterator; 
    public WildcardsTest(Map<K, C> map) { 
     iterator = map.entrySet().iterator(); 
    } 
} 

但是C参数真的是“不关心”的类型,只有复杂化在保持类型安全的同时,API还有什么方法可以摆脱它?

谢谢。

回答

4

像这样做,它会工作:

private final Iterator<? extends 
    Map.Entry<K, ? extends Collection<V>> 
> iterator; 

,您仍然可以这样使用迭代器:

public void foo(){ 
    while(iterator.hasNext()){ 
     Entry<K, ? extends Collection<V>> entry = iterator.next(); 
     Collection<V> value = entry.getValue(); 
    } 
} 

仅供参考,读取(从Java Generics and Collections原)the get and put principle

+0

精彩!再一次,解决方案是另一个间接xD级别 – fortran 2010-12-16 10:32:21

2

该分配是不正确的,虽然类型似乎完全匹配。

这两个? -wildcards可以绑定到两个不同的类。这样说吧,这是很明显的,有一个类型不匹配:

private Iterator<Map.Entry<K, ArrayList<V>>> iterator; 
public WildcardsTest(Map<K, HashSet<V>> map) { 
    iterator = map.entrySet().iterator(); 
} 

当你介绍了C,你“迫使他们”来指同一类。

相关问题