Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
548 views
in Technique[技术] by (71.8m points)

generics - Mixing nested type parameters and wildcards in Java

Why does trying to compile

public class GenericsFail {
    public static void main(String[] args) {
        accept(new HashMap<String, List<String>>());
    }

    public static void accept(Map<String, List<?>> multiMap) {}
}

give the error

GenericsFail.java:7: error: method accept in class GenericsFail cannot be applied to given types;
                accept(new HashMap<String, List<String>>());
                ^
  required: Map<String,List<?>>
  found: HashMap<String,List<String>>
  reason: actual argument HashMap<String,List<String>> cannot be converted to Map<String,List<?>> by method invocation conversion

The wildcard is only allowed if it's not nested inside List.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason is that the ? in List<?> could be "anything", but a different "anything" in each Map entry. That is, it would accept a List<String> in one entry, and a List<Integer> in another.

But you are passing in a Map that has the same type of List in every entry, so the type is not bound in the same way or the to same degree for freedom.

The "fix" is to lock the type to a specific type, but still being "anything" - just the same "anything* in every entry, by typing the method:

public static <T> void accept(Map<String, List<T>> multiMap) // complies

or if your method really doesn't need to know which type, use a wildcard to wrap the type:

public static void accept(Map<String, ? extends List<?>> multiMap) // compiles

This last version works because the type of the list, although being a wildcard, is fixed to an unknown, but consistent, type when called.


I find the typed version easier to read (and code), and the type is there for use should you decide later that your method needs to know the type.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...