Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Instantiating a generic class with no default constructor

I am trying to do this:

public class BaseTable<T extends TableEntry>

{

    protected int mRows;
    protected int mCols;
    protected ArrayList<T> mEntries;

    public BaseTable(int rows, int cols)
    {
        mRows = rows;
        mCols = cols;
        mEntries = new ArrayList<T>();
        for (int i = 0; i < rows; i++)
        {
            mEntries.add(new T(cols)); //this obv. doesn't work
        }
    }
}

Instantiating generics is hard enough as it is, but what makes this even harder is that T here does not have a default constructor, it takes a single int parameter in its constructor.

How can this be done?


I have asked a follow up question here too. I'd be grateful if you could answer that as well.

This question is related, but only is relevant where the classes are assumed to have a default constructor.

like image 451
bguiz Avatar asked Feb 27 '23 18:02

bguiz


1 Answers

It was already said, that you can't create an instance of T with new, so I would use the Factory Pattern or a Prototype Pattern

So your constructor would look like public BaseTable(int rows, int cols, LineFactory factory) with an appropriate instance of a factory.

In your case, I would prefer the Prototype Pattern, because your TableEntry objects are probably very light-weight. Your code would look like:

public BaseTable(int rows, int cols, T prototype)
{       
  mRows = rows;
  mCols = cols;
  prototype.setColumns(cols);
  mEntries = new ArrayList<T>();
  for (int i = 0; i < rows; i++)
  {
    @SuppressWarnings("unchecked")
    T newClone = (T)prototype.clone();
    mEntries.add(newClone); //this obv. does work :)
  }
}

public static void main(String[] args)
{
  new BaseTable<SimpleTableEntry>(10, 2, new SimpleTableEntry());
}
like image 97
Zappi Avatar answered Mar 05 '23 16:03

Zappi