Please find out about PECS, which, I think, Joshua Bloch introduced. You will find it in
Effective Java, 2nd and 3rd editions only. It means Producer=Extends, Consumer=Super. Also find out about generics being invariant, whereas inheritance is covariant.
Briefly, if you are using
Collection#addAll(), the argument passed is a Collection used as a producer and the producer has to supply something extending the type in question. If, for example, you have a
List<Animal>, you can usually add all the contents of a
List<Dog> or a
List<Cat> to it. Or of a
List<Animal>, because for the purposes of wild‑
cards, everything is a subtype of itself.
I think that the question about
Collection#removeIf() is different. You cannot expect that a
Predicate<Dog> will work instead of a
Predicate<Animal>, because a Dog might have a feature not accessible in
Animal. You can however find that a
Predicate<LivingBeing> can be applied to all
Animals, as well as plants or bacteria, because the
Animal is sure to have all the features of a
LivingBeing. So
extends won't work, but
super will. Remember that for the purposes of generics, everything is also a supertype of itself.