数组如何“记住”他们在Java中的类型? [英] How do arrays "remember" their types in Java?
问题描述
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 =新AA();
arr2 [0] = a; // ArrayStoreException在运行时
arr2 [1] = b;
列表< BB> listBB = new ArrayList<>();
列表listAA = listBB;
listAA.add(hello world.txt);
$ b code
$ b在上面的例子中,当我尝试 arr2 [0] = a
时, ArrayStoreException
。这意味着该数组会记住它必须接受的类型。但 List
不记得它们。它只是编译并运行良好。当我检索对象 BB
时,将引发 ClassCastException
。
所以问题是:
$ b $ ol
数组是如何记住它的类型的(我知道它叫做reification)。这是怎么发生的?
为什么在编译时不能检测 ArrayStoreException
,即当我执行 arr2 [0] = a
时,它可能会导致编译器错误,而不是在运行时检测它。
/ ol>
谢谢。
-
与泛型不同,数组的类型信息存储在运行时。从一开始它就是Java的一部分。在运行时,可以将
AA []
与BB []
区分开来,因为JVM知道它们的类型。 / b> -
一个
ArrayList
(以及其他的Collections框架)使用泛型, 。在运行时,泛型类型参数不可用,所以ArrayList< BB>
与ArrayList< AA>
;它们都是JVM的ArrayList
s。 编译器只知道
arr2
是一个 AA []
。如果你有一个 AA []
,编译器只能假定它可以存储 AA
。编译器不会检测到类型安全问题,因为您将 AA
放置在真正的 BB []
中,因为它只能看到 AA []
参考。与泛型不同,Java数组是协变的,因为 BB []
是 AA []
,因为 BB
是 AA
。但是这引入了你刚刚演示的可能性 - 一个 ArrayStoreException
,因为 arr2
引用的对象实际上是一个 BB []
,它不会处理 AA
作为元素。
Consider the following code:
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");
}
}
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
.
So the questions are:
How an array remembers its type (I know it's called "reification"). How this happens exactly?
And why only arrays are bestowed with this power but not
ArrayList
although it uses an array under its hood.Why can't
ArrayStoreException
be detected at compile time, i.e when I doarr2[0] = a
, it could cause a compiler error, instead of detecting it at runtime.
Thanks.
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 aBB[]
, because the JVM knows their types.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 anArrayList<BB>
is indistinguishable from anArrayList<AA>
; they are both justArrayList
s to the JVM.The compiler only knows that
arr2
is aAA[]
. If you have aAA[]
, the compiler can only assume that it can store anAA
. The compiler will not detect a type safety issue in that you are placing anAA
in what's really aBB[]
there, because it only sees theAA[]
reference. Unlike generics, Java arrays are covariant, in that aBB[]
is anAA[]
because aBB
is anAA
. But that introduces the possibility of what you just demonstrated - anArrayStoreException
, because the object referred to byarr2
is really aBB[]
, which will not handle anAA
as an element.
这篇关于数组如何“记住”他们在Java中的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!