通用类问题!

时间:2009-07-22 01:37:22

标签: java generics

我整天都在研究这个问题,但我找不到解决办法。我理解使用子类的问题以及编译器如何不知道该类实际上是什么,因为在调用add之前可以将其设置为其他类。我到处看,我仍然不知道如何解决这个问题。我有一个抽象类,它是一个文件包装器。文件包装器有一个sheetwrappers的arraylist。我希望具体的excelfile类能够将excelsheets添加到它的arraylist中,但我一直收到这个错误:

类型ArrayList中的方法add(capture#2-of?extends SheetWrapper)不适用于参数(ExcelSheet)

这是必要的代码。此处仅粘贴错误中涉及的部分.ExcelSheet也是一个抽象类。非常感谢任何帮助。谢谢!

public abstract class FileWrapper {

    protected ArrayList<? extends SheetWrapper> sheets;


public class ExcelFile extends FileWrapper {

    this.sheets = new ArrayList<ExcelSheet>();
    for(int i = 0; i < wb.getNumberOfSheets(); i++)
    {
        if(ParserTools.isLegitSheet(wb.getSheetAt(i)))
        {
            this.sheets.add(new ExcelSheet(null)); //ERROR HERE
        }
    } 

3 个答案:

答案 0 :(得分:1)

好吧,您将变量声明为扩展ArrayList的某些元素的“SheetWrapper”。这意味着您无法向其添加ExcelSheet的实例,因为它实际上可能是ArrayList扩展SheetWrapper的其他类型的add()

更确切地说,ArrayList<ExcelSheet> sheets = new ArrayList<ExcelSheet>(); for(int i = 0; i < wb.getNumberOfSheets(); i++) { if(ParserTools.isLegitSheet(wb.getSheetAt(i))) { sheets.add(new ExcelSheet(null)); //ERROR HERE } } this.sheets = sheets; 不是协变的。

如果您的所有代码实际上都在同一个地方,那么只需在分配之前填写您的列表

excelSheets

如果您需要从代码的不同部分执行此操作,只需将本地提升为另一个私有或受保护字段(例如sheets)和继承的{{1}},然后使用它。

答案 1 :(得分:0)

请参阅GenericsFAQ。你只想:

protected List<SheetWrapper> sheets;

请注意,使用接口类型“List”比变量声明的具体实现类“ArrayList”更好(除非该类需要特定的方法)。

答案 2 :(得分:0)

第二种可能性是使FileWrapper本身通用:

public abstract class FileWrapper<T extends SheetWrapper> {

    protected ArrayList<T> sheets;


    public class ExcelFile extends FileWrapper<ExcelSheet> {

        this.sheets = new ArrayList<ExcelSheet>();
        for(int i = 0; i < wb.getNumberOfSheets(); i++)
        {
            if(ParserTools.isLegitSheet(wb.getSheetAt(i)))
            {
                    this.sheets.add(new ExcelSheet(null));
            }
        }
    }
}

这样,您可以在ExcelFile中的任何位置使用工作表作为ExcelSheet的列表。