那是因为创建一个具体参数化类型的数组不是类型安全的,这就是为什么根本不允许这样做。
如果你尝试这样的代码,你会得到一个编译器错误:
List<String>[] arr = new ArrayList<String>[10]; // Compiler error: Generic Array creation
问题是泛型类型是不可具体化的——它们的类型信息在运行时不可用。同时,数组使用运行时可用的类型信息ArrayStoreCheck
来检查插入到数组中的元素是否与数组的类型兼容。因此,如果您混合使用数组和泛型,那么您最终可能会在运行时出现令人惊讶的行为。
例如,考虑以下代码:
List<String>[] arr = new ArrayList<String>[10]; // Suppose this was valid
Object[] objArr = arr; // This is valid assignment. A `List[]` is an `Object[]`
objArr[0] = new ArrayList<Integer>(); // There you go. A disaster waiting at runtime.
String str = arr[0].get(0); // Assigned an `Integer` to a `String`. ClassCastException
因此,如果编译了第一个赋值,那么编译器看起来不错的第四个赋值将ClassCastException
在运行时抛出 a。
但是,您可以创建原始类型数组 -ArrayList
或无界通配符参数化类型 - ArrayList<?>
,因为它们都是完全可具体化的类型。因此,以下数组创建是有效的:
List[] arr = new ArrayList[10];
List<?>[] arr2 = new ArrayList<?>[10];
由于没有与原始类型或无界通配符类型关联的类型信息,因此在运行时不会丢失任何内容。因此这些类型是可具体化的,它们是数组的合格组件类型。这就是为什么Entry[]
使用 代替Entry<K, V>[]
。
也可以看看: