2

Here is an example of the code that has been confusing me.

If I try to create a collection of a bounded type and assign the same variable to another variable that is another collection of unbounded unknown type, the code works.

List<? extends Number> numberList = new ArrayList<>();
List<?> anotherList = numberList; // OK

If I try to do the same inside a Map I get the "incompatible types" error.

Map<String, List<? extends Number>> numberMap = new HashMap<>();
Map<String, List<?>> anotherMap = numberMap; // ERROR

The error says:

Map<String,List<? extends Number>> cannot be converted to Map<String,List<?>>

Isn't Map<String,List<? extends Number>> a type of Map<String,List<?>>?

Here's the whole class for your convenience https://ideone.com/AZgV9H

I'm trying to understand why this isn't working and how should I change it in order to make it work.

user43624
  • 188
  • 1
  • 10
  • 3
    Generics are **not** covariant. Just like a `List` is not a `List`, a `Map>`is not a `Map`. – Boris the Spider Apr 08 '16 at 20:35
  • [Is List a subclass of List? Why aren't Java's generics implicitly polymorphic?](http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p) – Pshemo Apr 08 '16 at 20:39

1 Answers1

3

Just because a List<? extends Number> is a subtype of List<?> doesn't mean that Map<String, List<? extends Number>> is a subtype of Map<String, List<?>> for the same reason that a List<Number> is not a subtype of List<?> -- Java's generics are invariant.

To get List<Number> to be a subtype of List<?>, you had to add the wildcard with a bound. The solution is the same here -- add ? extends to List<?>.

Map<String, ? extends List<?>> anotherMap = numberMap;
rgettman
  • 176,041
  • 30
  • 275
  • 357