首先需要明白泛型是在编译器校验类型安全的,在运行期会将类型擦除,比如:
List<String> list = new ArrayList<>();
这段代码在运行期会被擦掉泛型,就等同于List list = new ArrayList();
其次 要明白集合中的泛型是不可变的,但是数组里的类型是可变的,比如:
List<String> list = new ArrayList<>();
List<Object> obs = list; // 将String的集合赋值给Object的集合会报错,这句会编译报错
但是将数组的引用赋值给其父类时,就不会报错。如:
String[] strs = new String[4];
Object[] obs = strs;// 这句就不会报错
正是由于数组的这个先天特性,导致即使加入泛型,仍然无法在编译器预先检查出类型安全问题,假如数组允许使用泛型:
Map<Stirng,Integer>[] maps = new Map<String,Integer>[];
Object[] obs = maps;
这时可以向obs中插入任何Object的子类,因为数组的先天特性是允许将子类数组转成父类数组的,所以在编译器是无法检测到类型安全问题的,这就违反泛型的初衷(泛型的初衷就是为了能在编译器检查出类型安全问题,并通过编译错误提示程序员)。