Java 1.6:创建列表数组<;T>;
为什么我不能创建一个列表数组Java 1.6:创建列表数组<;T>;,java,generics,Java,Generics,为什么我不能创建一个列表数组 List<String>[] nav = new List<String>[] { new ArrayList<String>() }; Eclipse说List和ArrayList是原始类型,但它编译 看起来很简单,为什么不起作用呢?一般来说,您不能创建泛型类型的数组 原因是JVM无法检查是否只将正确的对象放入其中(ArrayStoreException除外),因为运行时不存在List和List之间的差异 当然,您可以通过使用
List<String>[] nav = new List<String>[] { new ArrayList<String>() };
Eclipse说List和ArrayList是原始类型,但它编译
看起来很简单,为什么不起作用呢?一般来说,您不能创建泛型类型的数组 原因是JVM无法检查是否只将正确的对象放入其中(ArrayStoreException除外),因为运行时不存在
List
和List
之间的差异
当然,您可以通过使用原始类型List
或未绑定的通配符类型List
来欺骗编译器,然后将其强制转换为List
。但是你有责任只把列表
放进去,而不把其他列表放进去。好吧,回答你的问题
数组对象的组件类型
不能是类型变量或
参数化类型,除非它是
(无界)通配符类型。您可以
声明其元素类型为的数组类型
是类型变量还是参数化变量
类型,但不是数组对象
这是
当然,这很烦人。这一限制
有必要避免以下情况:
// 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);
//实际上不允许。
列表[]lsa=新列表[10];
对象o=lsa;
对象[]oa=(对象[])o;
List li=new ArrayList();
加(新整数(3));
//不可靠,但通过运行时存储检查
oa[1]=li;
//运行时错误:ClassCastException。
字符串s=lsa[1]。获取(0);
如果参数化类型的数组是 如果允许,前面的示例将 编译时没有任何未选中项 警告,但在运行时失败。 我们已经把类型安全作为首要任务 泛型的设计目标
没有确切的答案,但有一个提示: 最后一个示例有一个原始类型警告,因为您忽略了列表的类型化;通常,更好的(类型安全)方法是指定列表中包含哪些对象类型,您在前面的示例中已经这样做了(
list
,而不是list
)
使用数组不是最佳实践,因为它们的使用大多数时候都包含错误;使用集合类(列表、集合、映射等)可以使用打字和方便的方法来处理其内容;只需看看Collections类的静态方法
因此,只需使用前面答案的示例 另一种解决方案是扩展
LinkedList
(或ArrayList
等),然后创建子类的数组
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]);
}
私有静态类StringList扩展LinkedList{}
公共静态void main(字符串[]args)
{
StringList[]字符串=新的StringList[2];
字符串[0]=新的StringList();
strings[1]=新的StringList();
字符串[0]。添加(“测试1”);
字符串[0]。添加(“测试2”);
字符串[1]。添加(“测试3”);
字符串[1]。添加(“测试4”);
System.out.println(字符串[0]);
System.out.println(字符串[1]);
}
可以复制,但这违背了泛型的目的。“如果允许参数化类型的数组,上面的示例将在编译时没有任何未检查的警告,但在运行时失败。”这不是原因<代码>对象[]sa=新字符串[10];oa[1]=新整数(3)还将“编译时没有任何未检查的警告,但在运行时失败”。更重要的一点是,它应该在存储时失败,并出现ArrayStoreException(因此数组是运行时检查的)。但是运行时检查不能检查泛型,这就是为什么不允许创建参数化类型的数组。但是不能创建列表的数组
——这就是问题的关键(也是使用上一个示例的原因)。
List[] getLists() {
return new List[] { new ArrayList(), new ArrayList() };
}
// 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);
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]);
}