Java generics - special case of extended and super usage

extends, generics, java, super

Solution

The difference is in the type that is inferred for `T`: in `add1` it is the component type of the first collection (`Driver`), in `add2` it's the component type of the second collection (`Person`).

In this case `T` is not used in the method body, so there's no visible difference.

Problem

Is there any conceptual difference between these two methods? ``` public static <T> void add1(final Collection<T> drivers, final Collection<? super T> persons) { persons.addAll(drivers); } ``` and ``` public static <T> void add2(final Collection<? extends T> drivers, final Collection<T> persons) { persons.addAll(drivers); } ``` The following main method compiles without any warnings and executes without any runtime-exceptions. And the result is the expected one - 4. ``` public static void main(String[] args) { final Person person1 = new Person(); final Person person2 = new Person(); final Collection<Person> persons = new ArrayList<>(); persons.add(person1); persons.add(person2); final Driver driver1 = new Driver(); final Collection<Driver> drivers = new ArrayList<>(); drivers.add(driver1); add1(drivers, persons); add2(drivers, persons); System.out.println(persons.size()); } ``` I am aware of PECS principle, and since `persons` in the first method is a consumer, `super` should be use, respectively - `extends` should be used for `drivers` in the second method. But is there any gotchas? Any difference that I may miss? If not, which one of the versions is preferred, and why?

Original source