Несовместимые общие подстановочные знаки
В следующем фрагменте:
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>>> */
}
}
Назначение неверно, хотя типы, кажется, точно совпадают.
Я разработал грязный обходной путь, указав тип Collection в качестве другого универсального параметра, например так:
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, есть ли способ избавиться от него при сохранении безопасности типов?
Благодарю.
2 ответа
Сделайте так, и это будет работать:
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)
Назначение неверно, хотя типы, кажется, точно совпадают.
Два ?
карточки могут быть связаны с двумя разными классами. Проще говоря, совершенно очевидно, что существует несоответствие типов:
private Iterator<Map.Entry<K, ArrayList<V>>> iterator;
public WildcardsTest(Map<K, HashSet<V>> map) {
iterator = map.entrySet().iterator();
}
Когда вы вводите C
вы "заставляете их" относиться к одному и тому же классу.