2010-12-16 6 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(); 
    } 
} 

Для справки, читать the get and put principle (первоначально из Java Generics and Collections)

+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, вы «заставить их» обратиться к одному классу.

Смежные вопросы