Java generics - a special case of extended and superuser

Is there any conceptual difference between the 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 runs without any exceptions at runtime. And the result is the expected - 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 know the PECS principle, and since persons in the first method is a consumer, super should be used, respectively - extends should be used for drivers in the second method. But are there any mistakes? Any difference I can skip? If not, which version is preferred and why?

+4
source share
2 answers

The difference lies in the type that is displayed for T : in add1 this is the type of the component of the first collector ( Driver ), in add2 it is the type of the component of the second collector ( Person ).

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

+4
source

If A is a supertype of B, then B extends A, so there is no difference between the two versions.

Note that you can also use both super and extends :

 public static <T> void add3(final Collection<? extends T> drivers, final Collection<? super T> persons) { persons.addAll(drivers); } 
+2
source

Source: https://habr.com/ru/post/1496517/


All Articles