4

I guess this is a very confusing title, but I don't know what else to call - probably answered somewhere as well, but I couldn't find anything. Take this example:

List<Class<? extends Integer>> myList;
void foo() {
    bar(myList);
}
void bar(List<Class<?>> a) { /* ... */ }

It doesn't compile (not applicable arguments, it says). If I remove the bounding it works fine:

List<Class<?>> myList;
void foo() {
    bar(myList);
}
void bar(List<Class<?>> a) { /* ... */ }

Class<? extends Integer> is just more specific than Class<?>. How come it stops working? Note that this problem is only in the second level generics. If there wasn't a List, just Class<? extends Integer> and Class<?>, it works as well. But it seems to stop working when the generics is two ore more levels deep. Any reasons/workarounds/etc?

Luan Nico
  • 5,376
  • 2
  • 30
  • 60

1 Answers1

4

Note that List<B> is not a subtype of List<A> even if B is a subtype of A. Therefore, List<Class<? extends Integer>> is not a subtype of List<Class<?>> even though you can assign a Class<? extends Integer> object to a Class<?> variable. Just consider that in bar, it would be legal to invoke a.add(Object.class), as Class<Object> is a subtype of Class<?>.

You therefore want to extend the bar argument type to List<? extends Class<?>>.

misberner
  • 3,488
  • 20
  • 17