通用数组创建错误

65

我正在尝试做类似于这样的事情:

public static ArrayList<myObject>[] a = new ArrayList<myObject>[2];

myObject 是一个类。我遇到了这个错误:- 泛型数组创建(箭头指向 new)。


4
公共的静态变量a是一个长度为10的ArrayList数组,其中每个元素都是MyObject对象的ArrayList。 - houssam
12
这并不是重复的问题!那个问题是关于"new E[n]",而这个问题是关于"new Generic<E>[n]"。完全不同! - Cruise Liu
5个回答

73

你不能拥有泛型类的数组。Java并不支持这样做。

你应该考虑使用集合(collection)代替数组。例如,

public static ArrayList<List<MyObject>> a = new ArrayList<List<MyObject>();

另一个"解决方法"是创建一个类似于这样的辅助类

class MyObjectArrayList extends ArrayList<MyObject> { }

然后创建一个MyObjectArrayList数组。


这里有一篇好的文章,解释了为什么在语言中不允许这样做。文章给出了以下示例,说明如果允许这样做可能会发生什么:

List<String>[] lsa = new List<String>[10]; // illegal
Object[] oa = lsa;  // OK because List<String> is a subtype of Object
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
oa[0] = li; 
String s = lsa[0].get(0); 

如果它能编译,你将能够创建不一致的集合。(数组不是这样工作的,而是依靠在运行时抛出ArrayStoreException。)我会为您找到一个相关链接... - aioobe
1
这是一篇文章。http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html - aioobe
如果您尝试将文章中的示例从数组转换为ArrayList,则会在此处出现错误:List<Object> oa = lsa; // Type mismatch: cannot convert from List<List<String>> to List<Object> 为什么不允许泛型数组执行相同的检查呢? 您可以通过注释激活它,在该方法中失去一些向后兼容性。 - aalku
9
在没有泛型的情况下存在同样的问题:String[] x = new String[10]; Object[] y = x; y[1] = 10; //自动装箱 String z = x[1]; - aalku
2
我看不出这段代码有什么不同:Integer[] integerArray = new Integer[20]; Object[] objectArray = integerArray; objectArray[0] = "Hello world!"; integerArray[0].floatValue();该代码能通过编译,但在运行时将抛出以下异常: java.lang.ArrayStoreException: java.lang.String为什么? - Pierpaolo Pierpaoli

11

有比使用List更简单的创建通用数组的方法。

首先,让

public static ArrayList<myObject>[] a = new ArrayList[2];

然后进行初始化。

for(int i = 0; i < a.length; i++) {
     a[i] = new ArrayList<myObject>();
}

3
或者,为了避免原始类型,ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList<?>[2]; - newacct
像这样使用原始类型ArrayList将会影响类型安全性。例如,你可以编写 a[0] = new ArrayList<unrelatedObject>();,它也能够编译通过。无论如何,问题并不涉及数组的内容,所以我认为初始化并不相关。 - AndrewF

6

您可以做到

public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList<?>[2];

或者

public static ArrayList<myObject>[] a = (ArrayList<myObject>[])new ArrayList[2];

(前者可能更好。)两者都会导致未经检查的警告,您可以通过使用以下方式忽略或抑制它们:@SuppressWarnings("unchecked")。


-1
如果您想声明一个泛型类的ArrayList,可以尝试以下代码:
public static ArrayList<MyObject> a = new ArrayList<MyObject>();

这将为您提供一个包含myobject的ArrayList(大小为10),或者如果您只需要大小为2的ArrayList,则可以执行以下操作:

public static ArrayList<MyObject> a = new ArrayList<MyObject>(2);

或者你可能正在尝试创建一个ArrayList的ArrayList:

public static ArrayList<ArrayList<MyObject>> a = new ArrayList<ArrayList<MyObject>>();

虽然我不确定我上次说的是否正确...


-1

我觉得你使用了错误类型的括号。你无法定义一个泛型数组的原因是类型擦除

另外,你变量"a"的声明很脆弱,应该像这样:

List<myObject>[] a;

如果可以使用接口,请不要使用具体类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接