When you are using wildcard List<? super Dog> it means you can pass any type that is Dog or superclass of Dog and we can add anything that is of type Dog or any subclass of Dog, this happens because as we know in
polymorphism a parent type reference can hold its subclass object type.For example
(1).addAnimal(new ArrayList<Dog>());//method call or
(2).addAnimal(new ArrayList<Animal>());//method call
(3).public void addAnimal(List<? super Dog> animals) { }//called method
In the above calls the called method guirantees that adding anything that is Dog or subclass of Dog is acceptable weather you pass it (1) or (2) to (3).
But while using wildcard List<? extends Animal> you can pass it any List that is of generic type that is of type Animal or subtype of Animal.This syntax is used because we are telling the compiler that we are only using the List just for reading purpose and we will not add anything to it, if added the compiler will issue a compilation error.Error is given by compiler because imagine if addition was allowed in this syntax we would have added a wrong type into a wrong list since we could have passed it ArrayList<Dog> and we were free to add a Cat object into it and then at some point in runtime it would have given a Runtime Exception.
The <? extends Type> is meant to just use it for reading purpose and nothing else.