public void takeThing(ArrayList<? extends Animal> list)
means "do something with a list of any subclass of Animal".
public <T extends Animal> void takeThing(ArrayList<T> list)
means "do something with a list of some particular subclass (A.K.A. T) of Animal".
If I call list.get() on the first method, all I know about the returned type is that it extends Animal. On the second method, if I had another instance of List<T>, I know that whatever type T is, both lists would accept the same type.
To take it even further, if I say
Animal animal = list.get(0);
I can no longer say
list.add(animal);
even on the very same list, because we don't have a reference to the generic subtype. If however, I declare a List<T> where <T extends Animal>, I can now say
T animal = list.get(0);
list.add(animal);
because we know that list expects elements of type T.