为什么在运行时进行键入分配到数组组件



我正在阅读有效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是参考类型, 运行时间检查对数组组件的分配 确保分配的值可分配给组件。

现在我的理解是

  • 在编译时(以及运行时)数组变量上面的示例具有type a []
  • 编译器的职责是确保仅将[]的某些子类型分配给数组变量。
  • 阵列的组件(array [0])也是如此,编译器将仅检查分配的值是一个或某些子类型。

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

对我来说,似乎已经由编译器确定了错误。

好吧;编译器无法确定运行时array的实际类型。

让我们做一个琐碎的例子

array = myRandomFunction()>0 ? new A[10] : new B[10];

然后,array的实际类型可以是A[]B[],并且编译器无济于事。


如果您考虑一下;这类似于NullPointerException发生的事情:编译器不会抱怨以下内容(即使是否总是在运行时投掷)

Object a=null;
a.toString();

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

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

因此,这两条线在编译时均有效。

相关内容

  • 没有找到相关文章

最新更新