首页 > 解决方案 > 为什么在运行时对数组组件的赋值进行类型检查?

问题描述

我正在阅读 Effective java 的第 28 条,作者在其中写道

数组和泛型之间的第二个主要区别是数组是具体化的 [JLS, 4.7]。这意味着数组在运行时知道并强制执行其元素类型。

但为什么在运行时?例如,考虑两个类,其中 A 是 B 的父级

public static void main(String[] args) {
        A[] array = new B[10];
        array[0] = new A();
}

此代码引发 ArrayStoreException。对我来说,编译器似乎已经识别出错误。那么为什么编译器让它通过。是因为 JLS 不希望编译器那么聪明(慢)吗?

JLS 10.5对于类型为 A[] 的数组,其中 A 是引用类型,在运行时检查对数组组件的分配,以确保分配的值可分配给组件。

现在我的理解是

为什么将 A() 分配给数组 [0] 时,编译器不考虑实际的数组对象 (B[10])。是因为编译器没有可用的信息吗?

标签: javaarraystypes

解决方案


编译器可以在您发布的代码中检测到该错误,但一般情况下不会。

由于协方差,B[]可以将 分配给A[]第一行中的变量。如果将该数组传递给在第二行中执行赋值的方法,编译器将无法检测到数组的原始类型。

因此,这两行在编译时都是有效的。


推荐阅读