Crytis
Crytis

Reputation: 308

the difference between ? and letter on java generic

I hava a list:

List<Map<String, Integer>> list = new ArrayList<>();

and a method:

public  void doSth(List<Map<String, ?>> list) {
}

calling it like this:

doSth(list);

shows this error:

incompatible types: java.util.List<java.util.Map<java.lang.String,java.lang.Integer>> cannot be converted to java.util.List<java.util.Map<java.lang.String,?>>

However, this works:

public <V>  void doSth(List<Map<String, V>> list) {
}

What's the difference butween ? and V?

Upvotes: 0

Views: 175

Answers (1)

rgettman
rgettman

Reputation: 178253

Java treats type parameters that are embedded in within other type parameters differently from just plain old type parameters. Specifically, because Java's generics are invariant, any type parameters embedded must either match exactly or you may have to throw in a ? extends to satisfy the compiler's compile-time type safety requirement.

When the method expects a List<Map<String, ?>>, it's a list of maps that map strings to some specific yet unknown type, which may not be Integer. The map may use any object type.

When you declare V, the compiler resolves V to Integer so that an exact match to the method is made.

You can also do one of the following: Use a wildcard in the declaration of list:

List<Map<String, ?>> list = new ArrayList<>();

or insert a ? extends so the method can expect a subtype and not necessarily the exact match with regard to generics:

public static void doSth(List<? extends Map<String, ?>> list) {
}

or you can just match Integer for Integer:

public static void doSth(List<Map<String, Integer>> list) {
}

Upvotes: 1

Related Questions