简体   繁体   中英

Why am I getting a capture-of applicability error in my class?

I wrote the following code:

public class HashMapImpl<Key,Value>{
    Key key;
    Value value;

    List<? extends Key> keylist;
    List<? extends Value> valuelist;

    public HashMapImpl(Key k,Value v){
        this.key = k;
        this.value = v;

        keylist = new ArrayList<Key>();
        valuelist = new ArrayList<Value>();
    }

    public Value put(Key k, Value v){
        this.keylist.add(k);
    }
}

I am getting this error on add() :

The method add(capture#3-of ? extends Key) in the type List<capture#3-of ? extends Key> List<capture#3-of ? extends Key> is not applicable for the arguments ( Key )

Why is this happening? How can I fix it?

There's no reason to use ? extends Key ? extends Key in this use case; that syntax is for a list type that could be more restrictive, but isn't necessarily more restrictive than Key . Because the compiler doesn't know that it's just a List<Key> , it won't let you add Key , because of the case where the generic type of the list *does happen to be more restrictive than Key .

One way to think about it is that, in the case of Collection s:

  • It's easy to add stuff to List<? super Foo> List<? super Foo> , but you don't know much about the object; get(int index) returns an Object , not a Foo .
  • It's hard to add stuff to List<? extends Foo> List<? extends Foo> , but you know a lot about the object; get(int index) does return a Foo .

tl;dr Just use:

List<Key> keylist;
List<Value> valuelist;

and your program will work.

Further reading: Canonical Java Generics FAQ, with a link to the section on bounded wildcards

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