Java 泛型上限规则不会破坏 Liskov 替换吗?

Doesn't Java Generics upper bound rule breaks Liskov substitution?

我正在阅读有关 Java 泛型的内容,以下部分似乎有问题:

public class Farm {
  private List<Animal> animals;

  public void addAnimals(Collection<Animal> newAnimals) {
    animals.addAll(newAnimals);
  }
}

farm.addAnimals(cats); // Compilation error
farm.addAnimals(dogs); // Compilation error

Cat 和 Dog 是 Animal 的子类。

为了使其工作,需要定义一个具有上限的通配符类型:

public void addAnimals(Collection<? extends Animal> newAnimals)

根据 Liskov 替换的定义,我是否可以互换使用子类和超类而不需要设置上限:

Substitutability is a principle in object-oriented programming stating that an object (such as a class) and a sub-object (such as a class that extends the first class) must be interchangeable without breaking the program.

只有猫的集合不是任何动物集合的子类。

这和编译错误是好事。否则,您可以声明一个只有猫的集合,然后将狗放入其中。麻烦接踵而至。