数组是协变的,所谓协变是指如果Sub是Super的子类,那么Sub[]是Super[]的子类,但这在列表中是不成立的。协变是有缺陷的,或者说有风险的。例如:
//数组协变的缺陷Object[] objs = new String[10];objs[0] = new String[5];//RunTimeException: ArrayStoreException: [Ljava.lang.String;String first = (String)objs[0];//List不支持协变List
因此,一般而言,能使用List则使用List,尽量避免使用数组。
Java不支持创建泛型,谈到这儿,就得扯到泛型擦除机制了。假设数组支持泛型,那么因为数组的协变特性,在编译期间编译器无法进行类型检查,而在运行期,泛型类型被擦除。例如在运行期,下面三个变量都是List类型。
ListstrList = new ArrayList<>();List intList = new ArrayList<>();List orgList = new ArrayList();复制代码
如果,数组支持泛型,那么下面的代码就会成立,但runtime时则抛出类型错误。
Object[] objs = new ArrayList()[10]; //假设数组支持泛型objs[0] = new ArrayList ();//编译器被骗,不知道有类型错误复制代码
所以说,为了保证Java的类型安全,是不支持创建泛型数组的。
注意:上文提到的只是不支持创建泛型数组,但并没有限制声明泛型数组。例如下面这条语句就是合法的。
//创建原始类型数组,然后强转,合法语句ArrayList[] obj = (ArrayList [])new ArrayList[10];obj[0] = new ArrayList<>();//添加一个ArrayList 对象,合法语句obj[1] = new ArrayList ();//编译错误:不兼容的类型。复制代码