简体   繁体   中英

Incompatible generic wildcard captures

in the following snippet:

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>>> */
    }
}

The assignment is incorrect, although the types seem to match exactly.

I've devised a dirty workaround by specifying the type of the Collection as another generic parameter, like this:

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();
    }
}

But that C parameter is really a "don't care" type that only complicates the API, is there any way to get rid of it while maintaining type safety?

Thanks.

Do it like this and it will work:

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

You can still use the iterator like this:

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

For reference, read the get and put principle (originally from Java Generics and Collections )

The assignment is incorrect, although the types seem to match exactly.

The two ? -wildcards can be bound to two different classes. Put it this way, it is quite obvious that there is a type mismatch:

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

When you introduce the C , you "force them" to refer to the same class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM