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

ArrayList类型的方法add(capture#2-of?extended 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
        }
    }

最佳答案

好吧,您将变量声明为“扩展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),然后使用它即可。

08-04 12:05