为什么我不能创建List数组?
List<String>[] nav = new List<String>[] { new ArrayList<String>() };
Eclipse说“无法创建List的通用数组”
或
ArrayList<String>[] nav = new ArrayList<String>[] { new ArrayList<String>() };
Eclipse说“无法创建ArrayList的通用数组”
或
List<String>[] getListsOfStrings() {
List<String> groupA = new ArrayList<String>();
List<String> groupB = new ArrayList<String>();
return new List<String>[] { groupA, groupB };
}
但我可以这样做:
List[] getLists() {
return new List[] { new ArrayList(), new ArrayList() };
}
Eclipse说List和ArrayList是原始类型但它编译......
看起来很简单,为什么它不起作用?
答案 0 :(得分:29)
好吧,generics tutorial给出了你问题的答案。
数组对象的组件类型 可能不是类型变量或 参数化类型,除非是 (无界)通配符类型。你可以 声明其元素类型的数组 types 是一个类型变量或参数化 类型,但不是数组对象。
这是 很烦人,可以肯定。这个限制 有必要避免以下情况:
// Not really allowed. List<String>[] lsa = new List<String>[10]; Object o = lsa; Object[] oa = (Object[]) o; List<Integer> li = new ArrayList<Integer>(); li.add(new Integer(3)); // Unsound, but passes run time store check oa[1] = li; // Run-time error: ClassCastException. String s = lsa[1].get(0);
如果是参数化类型的数组 允许,前面的例子会 没有任何未选中的编译 警告,但在运行时失败。 我们把类型安全作为主要的 仿制药的设计目标。
答案 1 :(得分:14)
通常,您无法创建泛型类型的数组。
原因是JVM无法检查是否只将正确的对象放入其中(使用ArrayStoreExceptions),因为List<String>
和List<Integer>
之间的差异在运行时是不存在的。
当然,您可以使用原始类型List
或未绑定的通配符类型List<?>
欺骗编译器,然后将其(使用未经检查的强制转换)强制转换为List<String>
。但是,您有责任只在其中放置List<String>
而不在其他列表中。
答案 2 :(得分:1)
没有确切答案,但提示:
最后一个示例有一个原始类型警告,因为您省略了列表的典型化;它通常是一种更好的(类型安全)方法来指定列表中包含哪些对象类型,您已在前面的示例(List<String>
而不是List
中)中进行了这些操作。
使用数组不是最佳实践,因为它们的使用大多数时间都包含错误;使用Collection类(List,Set,Map,...)可以使用典型化和方便的方法来处理它们的内容;只需看一下Collections类的静态方法。
因此,只使用前一个答案的例子。
答案 3 :(得分:0)
另一个解决方案是扩展LinkedList<String>
(或ArrayList<String>
等),然后创建子类的数组。
private static class StringList extends LinkedList<String> {}
public static void main(String[] args)
{
StringList[] strings = new StringList[2];
strings[0] = new StringList();
strings[1] = new StringList();
strings[0].add("Test 1");
strings[0].add("Test 2");
strings[1].add("Test 3");
strings[1].add("Test 4");
System.out.println(strings[0]);
System.out.println(strings[1]);
}