通用阵列创建与Array.newInstance()

时间:2010-09-16 23:22:46

标签: java arrays generics iterator

我正在写一个有两个ArrayList字段的类。一个用于包含自定义对象。另一个用于包含自定义集合对象(也可能包含这些字段):

private ArrayList<SomeClass> myObjList;                  // Just objects
private ArrayList<SomeCollectionClass> myCollectionList; // Collections of objects

为了实现Collection<E>接口,我编写了一个iterator()方法:

public Iterator<SomeClass> iterator() { ... }

但作为一种方便的方法,我也开始编写一个deepIterator()来为Iterators中的每个集合返回myCollectionList - Iterators的集合 - 事情变得非常混乱很快:

public Iterator<SomeClass>[] deepIterator() {
    int numIterators = this.myCollectionList.size();
    Iterator<SomeClass>[] iters = (Iterator<SomeClass>[]) new Iterator<SomeClass>[numIterators]; // not allowed
    for (int i = 0; i <= numIterators; i++) {
        iters[i] = this.myCollectionList.get(i).iterator();
    }
    return iters;
}

并且编译器抛出"generic array creation"错误。我理解为什么会这样,我不明白的原因是:

    public Iterator<SomeClass>[] deepIterator() {
    int numIterators = this.myCollectionList.size();
    Iterator<SomeClass>[] iters = (Iterator<SomeClass>[])(Array.newInstance(Iterator.class, numIterators)); // allowed
    for (int i = 0; i <= numIterators; i++) {
        iters[i] = this.myCollectionList.get(i).iterator();
    }
    return iters;
}

编译得很好。谁能解释一下?我并不真正关心array[]与某些Collection<E>类(ArrayList或者你有什么)作为返回类型的优点,我只是因为声明/实例化/而神秘化了初始化线。提前谢谢!

2 个答案:

答案 0 :(得分:1)

如果你宣布你的第二件物品会有帮助吗?

private ArrayList<Collection<SomeClass>> myCollectionList;

处理数组和迭代器看起来像a $$中的痛苦。我之前使用类似的泛型嵌套集合中的集合,它工作正常。然后我只使用普通的集合API调用在嵌套的for循环中迭代它。

答案 1 :(得分:0)

不同之处在于,在第一个片段中,您在创建阵列时指定了迭代器的类型参数,但在第二个片段中则没有。如果对类型参数使用无界通配符:

Iterator<SomeClass>[] iters = (Iterator<SomeClass>[]) new Iterator<?>[numIterators];

或原始类型:

Iterator<SomeClass>[] iters = (Iterator<SomeClass>[]) new Iterator[numIterators];

它就像第二个片段一样编译,即它只会发出未经检查的警告。

PS:Java Language Specification, §15.10禁止创建不可恢复的组件类型的数组。

PPS:就个人而言,如果一个API不必要地强迫我处理Iterator对象,我会很生气,因为不能使用扩展的for循环进行迭代。如果您要公开列表,为什么不公开Collection(或至少Iterable)?这对您和您的来电者来说更容易。