如何正确实现嵌套泛型?

时间:2016-05-22 11:10:19

标签: java generics

我在一个类型List<List<Value>>的类上有一个属性,我试图用一个类来实例化它,这个类是这些接口和类的子类型,如下所示:

public List<List<Value>> rows = new DbRowList<MyRow>();

其中DbRowList是一种扩展ArrayList的类型:

public class DbRowList<E extends List<Value>> extends ArrayList<E> implements List<E> {

    public boolean add(E element) {
        MyRow row = new MyRow();
        return super.add(row); // Compile-time error
    }
}

MyRow是:

public class MyRow extends ArrayList<Value> implements List<Value> {
    public Table table;
}

然而,由于DbRowList.add()的返回语句中存在错误,因此无法编译:

The method add(E) in the type ArrayList<E> is not applicable for the arguments (MyRow)

为什么不适用? MyRow扩展ArrayList<Value>List本身就是{{1}}。

3 个答案:

答案 0 :(得分:0)

您的错误消息不言自明:编译器期望将E类型的参数传递给super.add()。您的代码覆盖 add()方法,因此必须通过传递E类型的对象来执行此操作。所以你的代码应该是这样的:

public boolean add(E element) {
    return super.add(E); // no error here
}

如果您想知道如何使用您的课程,只需在外面创建MyRow对象并将其传递给:

List<List<Value>> rows = new DbRowList<MyRow>();
MyRow row = new MyRow();
rows.add(row);

答案 1 :(得分:0)

首先,您不需要这些&#34; implements List<E>&#34;,因为ArrayList本身实现了List

关于编译错误,所以使用和理解泛型是错误的。当您为DbRowList类的实例指定此类型变量时,您将能够添加特定类的特定实例,因此这段代码将编译并工作:

public boolean add(E element) {
    return super.add(element); 
}

public static void main(String[] args) {
    new DbRowList<MyRow>().add(new MyRow());
}

但是如果你想强制编译你的例子,你总是可以转换为泛型类型E,因为泛型在运行时没有任何内容,列表可以包含任何类型的实例:

public boolean add(E element) {
    MyRow row = new MyRow();
    return super.add((E) row);
}

答案 2 :(得分:0)

你为什么要这样做?

重写方法以添加空arrayList而不是实际参数值。元素不会传递到任何地方。

原因很简单:你试图将它传递给想要

的super.add
E

但你通过了

ArrayList<E>.

你应该做的只是不要覆盖方法,但要正确定义类:

public class DbRowList<E extends List<Value>> extends ArrayList<E>{

}

void testMethod(){
    List<List<Value>> rows = new DbRowList<>();
    rows.add(new ArrayList<>());
}

编辑:实际上,在输入时我明白它并不完全是你想要的,所以请澄清:你需要保存行还是将元素保存到指定的行?我所描述的是保存整行,但您可能需要的是指向行的映射。然后,您可以将元素添加到指定的行,而无需创建所需的新行或加载/搜索行。