Generic Class Problems!

I have been research this all day and I cannot find a solution. I understand the problem of using subclasses and how the compiler wont know what the class will actually be because of the possibility of setting setting it to something else before calling add. I have look everywhere and I still don’t know how to fix this problem. I have an abstract class that is a file wrapper. the file wrapper has an arraylist of sheetwrappers. I want the concrete class of excelfile to be able to add excelsheets to its arraylist but I keep getting this error:

The method add(capture#2-of ? extends SheetWrapper) in the type ArrayList is not applicable for the arguments (ExcelSheet)

Here is the necessary code. Only the parts that are involved in the error are pasted here.ExcelSheet is also an abstract class. Any help would be very very appreciated.Thanks!

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
        }
    } 

Answer

Well, you declared a variable as an “ArrayList of some elements that extend SheetWrapper“. This means that you cannot add an instance of ExcelSheet to it, since it could actually be an ArrayList of some other type that extends SheetWrapper.

More precisely speaking, add() is not covariant.

If all your code is actually in the same place, then just fill your list before assigning it:

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;

If you need to do it from different parts of code, just lift that local to be another private or protected field (e.g. excelSheets) alongside the inherited sheets, and use that.

Leave a Reply

Your email address will not be published. Required fields are marked *