问题描述
限时送ChatGPT账号..考虑以下代码:
class AA { }
class BB extends AA { }
public class Testing {
public static void main(String[] args) {
BB[] arr = new BB[10];
AA[] arr2 = arr;
BB b = new BB();
AA a = new AA();
arr2[0] = a; // ArrayStoreException at runtime
arr2[1] = b;
List<BB> listBB = new ArrayList<>();
List listAA = listBB;
listAA.add("hello world.txt");
}
}
在上面的例子中,当我尝试 arr2[0] = a
时,我得到了 ArrayStoreException
.这意味着数组记住它必须接受的类型.但是 List
不记得它们.它只是编译并运行良好.当我检索对象 BB
时,将抛出 ClassCastException
.
In the above example, I get the ArrayStoreException
when I try arr2[0] = a
. That means the array remembers what type it must accept. But the List
does not remember them. It simply compiles and runs fine. The ClassCastException
will be thrown when I retrieve the object BB
.
所以问题是:
数组如何记住它的类型(我知道它被称为具体化").这究竟是怎么发生的?
How an array remembers its type (I know it's called "reification"). How this happens exactly?
为什么只有数组被赋予这种能力而不是 ArrayList
尽管它在其引擎盖下使用了一个数组.
And why only arrays are bestowed with this power but not ArrayList
although it uses an array under its hood.
为什么在编译时检测不到ArrayStoreException
,即当我执行arr2[0] = a
时,它可能会导致编译器错误,而不是在运行时检测它.
Why can't ArrayStoreException
be detected at compile time, i.e when I do arr2[0] = a
, it could cause a compiler error, instead of detecting it at runtime.
谢谢.
推荐答案
与泛型不同,数组的类型信息是在运行时存储的.从一开始,这就是 Java 的一部分.在运行时,可以将 AA[]
与 BB[]
区分开来,因为 JVM 知道它们的类型.
The type information for arrays, unlike for generics, is stored at runtime. This has been part of Java since the beginning of it. At runtime, a AA[]
can be distinguished from a BB[]
, because the JVM knows their types.
ArrayList
(以及集合框架的其余部分)使用泛型,它受类型擦除的影响.在运行时,泛型类型参数不可用,因此 ArrayList
与 ArrayList
无法区分;它们都只是 JVM 的 ArrayList
s.
An ArrayList
(and the rest of the Collections framework) uses generics, which is subject to type erasure. At runtime, the generic type parameter is not available, so an ArrayList<BB>
is indistinguishable from an ArrayList<AA>
; they are both just ArrayList
s to the JVM.
编译器只知道arr2
是一个AA[]
.如果你有一个AA[]
,编译器只能假设它可以存储一个AA
.编译器不会检测类型安全问题,因为您将 AA
放在真正的 BB[]
中,因为它只能看到 AA[]
参考.与泛型不同,Java 数组是协变的,因为 BB[]
是 AA[]
,因为 BB
是 AA代码>.但这引入了你刚刚演示的可能性 -
ArrayStoreException
,因为 arr2
引用的对象实际上是一个 BB[]
,它不会将 AA
作为元素处理.
The compiler only knows that arr2
is a AA[]
. If you have a AA[]
, the compiler can only assume that it can store an AA
. The compiler will not detect a type safety issue in that you are placing an AA
in what's really a BB[]
there, because it only sees the AA[]
reference. Unlike generics, Java arrays are covariant, in that a BB[]
is an AA[]
because a BB
is an AA
. But that introduces the possibility of what you just demonstrated - an ArrayStoreException
, because the object referred to by arr2
is really a BB[]
, which will not handle an AA
as an element.
这篇关于数组如何“记住"?他们在 Java 中的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论