Я немного озадачен тем, как дженерики Java обрабатывают наследование/полиморфизм.
Предположим следующую иерархию -
Животное (родитель)
Собака - Кот (Дети)
Предположим, у меня есть метод doSomething(List<Animal> animals). По всем правилам наследования и полиморфизма я бы предположил, что List<Dog> - это List<Animal> а List<Cat> - это List<Animal> - и поэтому любой из них может быть передан этому методу. Не так. Если я хочу добиться такого поведения, я должен явно указать методу, чтобы он принимал список любого подкласса Animal, сказав doSomething(List<? extends Animal> animals).
Я понимаю, что это поведение Java. У меня вопрос почему? Почему полиморфизм обычно неявный, но когда дело доходит до дженериков, он должен быть указан?