Java 数组协变是否违反里氏代换原则?

Does Java array covariance violate Liskov Substitution Principle?

我正在阅读为什么 Java 中的数组协方差不好 (Why are arrays covariant but generics are invariant?)。如果 DogAnimal 的子类型,那么 Dog[]Animal[] 的子类型。这是一个问题,因为可以这样做:

Animal[] animals = new Dog[1];
animals[0] = new Cat();

这与实现的泛型不同 'correctly'。 List<Dog> 不是 List<Animal>

的子类型

我试图理解它为什么不好的本质,并且刚刚阅读了有关 LSP 的内容。它是否以任何方式违反了 LSP?似乎没有明显的违规行为。

Did it violate the LSP in any way?

是的。

There doesn't seem to be a clear violation.

你自己的例子是违规的。以下代码工作正常:

Animal[] animals = new Animal[1];
animals[0] = new Cat();

但是,如果现在将 Animal[] 替换为它的子类型 Dog[],代码将不再有效(也就是说,它会导致异常,而以前不会)。所以类型 Dog[] 不能在任何可以使用它的超类型 Animal[] 并且违反 LSP 的地方使用。

将其放入 LSP 的措辞中:如果我们考虑 属性“new Cat() 可以作为元素分配”,类型 Animal[] 满足此 属性 ,但它的子类型 Dog[] 没有。