您不能安全地创建通用数组。有效的Java 2nd Edition在“
泛型 ”
一章中进行了详细介绍。从第119页的最后一段开始:
为什么创建通用数组是非法的?因为它不是类型安全的。如果合法,则编译器在其他正确程序中生成的强制转换在运行时可能会失败,并带有
ClassCastException。这将违反通用类型系统提供的基本保证。为了更具体,请考虑以下代码片段:
// Why generic array creation is illegal - won't compile!List<String>[] stringLists = new List<String>[1]; // (1)List<Integer> intList = Arrays.asList(42); // (2)Object[] objects = stringLists; // (3)objects[0] = intList; // (4)String s = stringLists[0].get(0); // (5)让我们假装创建通用数组的第一行是合法的。第2行创建并初始化一个
List<Integer>包含单个元素的。第3行将List<String>数组存储 到Object
数组变量中,这是合法的,因为数组是协变的。第4行将int存储List<Integer>到Object数组的唯一元素中,这是成功的,因为泛型是通过擦除实现的:List<Integer>实例List的运行时类型为,List<String>[]实例的运行时类型
为List[],因此此赋值不会生成ArrayStoreException。现在我们有麻烦了。我们已将List<Integer>
实例存储到声明为仅容纳的数组中List<String>
实例。在第5行中,我们从此数组的唯一列表中检索唯一元素。编译器会自动将检索到的元素强制转换为String,但它是一个Integer,因此我们ClassCastException在运行时会得到一个
。为了防止这种情况发生,第1行(创建通用数组)会产生编译时错误。
因为数组和泛型不能很好地结合(以及其他原因),所以通常最好使用
Collection对象(尤其是
List对象)而不是数组。



