There two mayor difference. The wildcard (?) is used to say "any class", so <? extends Animal> would something like "any class that extends Animal" and <? super Animal> would be "any class that is a superclass of Animal".
For example, let's suppose that Dog extends Animal and Cat extends Animal. And we know that Animal extends Object (implicitly).
So, we could do this:
List<? extends Animal> list1 = new ArrayList<Dog>(); (it's OK, Dog extends Animal) List<? extend Animal> list2 = new ArrayList<Cat>(); (it's OK, Cat extends Animal) List<? extends Dog> list3 = new ArrayList<Animal>(); (NOT OK) List<? super Dog> list4 = new ArrayList<Animal>(); (it's OK, Animal is a superclass of Dog)
Notice that wildcards can ONLY by used on declaration. These is absurd: List<? extends Animal> list1 = new ArrayList<? extends Animal>(); (Horrible wrong)
So, why is there that difference? Well, if you declare a class with a generic using the wildcard that extends another class, you can't ADD anything to it. This will result as a big compile error: