static void basket(List<? super Apple>list){list.add(new Object());}
you are telling compiler, that you provide List with parameter of type Object or Fruit (if I remember correctly) or Apple.
So, it will only allow to insert type, which won't break any of these conditions.
Suppose, you call basket method with parameter of type List<Apple>, and now you want to insert Object. This would corrupt type safety.
Suppose, you want to insert Apple or any sub-class of Apple. This is OK, because it can be safely upcasted to any type, that can occur as parameter in List<? super Apple>
List<? super Animal> dlist = new ArrayList<Dog>(); //NO <? super Animal> says that dlist can only hold ref of the List (object of a class that implements List) object parameterized with Animal or super class of Animal that is Object in our case.
The method's argument List<? super Sub1>, does two things, it dictates, 1) what can be passed into the method as an argument and 2) what can be added to that argument list within that method.
? super Sub1 means we can invoke that method with a list that is of type Sub1 or above. In which case the following three are possible: List<? super Sub1 > l = new ArrayList<Sub1>(); List<? super Sub1 > l2 = new ArrayList<Top>(); List<? super Sub1 > l3 = new ArrayList<Object>();
Inside the method, you can add any object that is of type Sub1 or any of its subtypes ie. it expects an object that is-a Sub1. So that whatever can be done on Sub1 can be done on its subtypes. Therefore the following are allowed. s.add(new Sub1()); s.add(new Sub2()); s.add(new Sub3());