ArrayList<String>[] arrayList = new ArrayList[3];//不报错
ArrayList<String>[] arrayList = new ArrayList<String>[3];//报错
泛型:编译期间检查,运行期间类型擦除
数组:运行期间检查
第一种情况允许的原因:
因为创建了一个未指定泛型类型的ArrayList数组,然后将它赋值给指定了泛型类型为String的ArrayList数组引用。但是经过擦除后,等同于未指定泛型类型的arrayList数组,都是Object类型。
第二种情况不被允许的原因:
因为Java不允许直接创建带有具体泛型类型的数组(如ArrayList<String>)。这是因为泛型信息在运行时会被擦除,而数组需要在运行时知道它们的具体类型,换位思考,如果被允许,运行的时候是object类型,那我可以往arrayList集合里面添加Integer类型的对象,但是我的泛型是String类型的,二者冲突(你会好奇,泛型编译期就检查了,怎么可能让你在运行的时候添加Integer类型的对象,其实通过桥接的方式,就可以实现,我将代码写在下面了)。
// 假设Java允许这样的声明
ArrayList<String>[] stringLists = new ArrayList<String>[1];// 由于类型擦除,运行时这个数组只知道它包含ArrayList类型,不知道具体是ArrayList<String>
Object[] objectArray = stringLists;// 这里没有编译错误,因为我们是通过Object数组引用来操作的
// 这样就绕过了编译时的类型检查
objectArray[0] = new ArrayList<Integer>();// 这里尝试获取第一个元素,并认为它是ArrayList<String>
// 但实际上它是ArrayList<Integer>,这就导致了类型不安全
ArrayList<String> firstList = stringLists[0];