Java 中的数组
Collection 系列文章的总目录:
- Collection 体系的三个核心约定
- Sorted & Navigable
- Iterator & Iterable
- Java 中的数组
- ArrayList
- LinkedList
- HashMap
- LinkedHashMap
- TreeMap
- HashSet/LinkedHashSet/TreeSet
数组是JVM的元素提供的定长数据结构,是类型安全的。
字节码:
https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5
数组相关的字节码指令:
- anewarray:创建引用类型的数组
- arraylength:获取一个数组的长度
- multianewarray:创建多维数组
- newarray:创建基本类型的数组
- ....
创建数组对应的字节码:
// ANEWARRAY java/lang/Object
Object[] refArr = new Object[0];
// NEWARRAY T_INT
int[] intArr = new int[0];
数组类型在字节码中的表示:
LOCALVARIABLE refArr [Ljava/lang/Object; L1 L3 1
LOCALVARIABLE intArr [I L2 L3 2
字节码中数据类型的表示:
- L + 全限定类名:引用类型
- byte:B
- short:S
- int:I
- long:J
- float:F
- double:D
- boolean:Z
- char:C
- void:V
- 一维 byte 数组:[B
- 二维 byte 数组:[[B
类型安全:
JVM中,数组的会存储对象信息,这样就禁止了往数组放入其他类型的对象。
将一个 Integer[] 强转成 Object[],并放入一个 Object:
Integer[] intArr = new Integer[5];
Object[] refArr = (Object[])intArr;
// java.lang.ArrayStoreException
refArr[0] = new Object();
会抛出 ArrayStoreException
由此可见,数组是真泛型。
泛型:
对应的,Java 中的泛型是假泛型,不是类型安全的,因为它只是源码层面的,编译器编译成字节码后就会把泛型擦除,变成Object类型,这样在运行时就可以通过反射或者其他手段往里面放不是泛型指定的类型,从而导致取出对象时发生 ClassCastException
。
调用泛型对象的 getClass():
List<String> strings = new ArrayList<>();
List<Integer> integers = new ArrayList<>();
// true, java.util.ArrayList
System.out.println(strings.getClass() == integers.getClass());
问题:
Q:声明一个包含泛型对象的数组,会发生什么?
A:参考这位老哥的分析:https://blog.csdn.net/yi_Afly/article/details/52058708