generics + new = problem

Discussion in 'Java' started by Mauro, Apr 20, 2007.

  1. Mauro

    Mauro Guest

    HI All,
    This problem is not new, I read a lot, but I still do not understand
    if there's a solution or not (shame on me).

    The problem is: I want to build a generic class that constructs new
    instances of the type variable.
    i.e.:

    public interface IOCElement extends Serializable, ChangeEmitter {
    public String getName();
    }

    public class GenericListModel<T extends IOCElement> extends
    AbstractListModel
    implements ComboBoxModel, ChangeListener {
    static final long serialVersionUID = 1l;

    private ArrayList<T> tList = null;

    public GenericListModel() {
    tList = new ArrayList<T>();
    }

    // AbstractListModel implementation
    public Object getElementAt(int index) { return tList.get(index); }
    public int getSize() { return tList.size(); }
    // needed for FreeMarker
    public ArrayList<T> getTasks() { return tList; }
    // ComboBoxModel implementation
    transient private int selectedItem = -1;
    public Object getSelectedItem() { return (selectedItem>=0)?
    get(selectedItem): null; }
    public void setSelectedItem(Object anItem) { if (anItem instanceof
    IOCElement) { selectedItem = pos(((IOCElement)anItem).getName()); } }

    // API
    public T get(int index) { return tList.get(index); }
    public int add(String name) {
    int index = 0;
    if (tList.add(new T(name))) {
    index = tList.size();
    tList.get(index-1).addChangeListener(this);
    selectedItem = -1;
    fireIntervalAdded(this, index, index);
    }
    return index-1;
    }
    ..... etc. etc.

    Everything is ok BUT the line that reads:
    if (tList.add(new T(name))) {

    I understand that erasures make this difficult for the compiler, but:
    Is there a way around this (possibly using newInstance(),
    constructor() or whatever)?
    Can someone tell me exactly what I should do? (if anything can be
    done).

    Thanks in Advance
    Mauro
    Mauro, Apr 20, 2007
    #1
    1. Advertising

  2. Mauro

    Tom Hawtin Guest

    Mauro wrote:
    >
    > The problem is: I want to build a generic class that constructs new
    > instances of the type variable.


    > if (tList.add(new T(name))) {


    Even if T was, say, an interface you would still have a problem,
    generics or not.

    What you need is a factory.

    interface NamedObjectFactory<T> {
    T create(String name);
    }
    ....
    interface IOCElementSubtype extends IOCElement {
    ...
    }
    ....
    class ConcreteIOCElement implements IOCElementSubtype {
    ...
    }
    ....
    new GenericListModel<IOCElementSubtype>(
    new NamedObjectFactory<IOCElementSubtype>{
    public IOCElementSubtype create(String name) {
    return new ConcreteIOCElement(name);
    }
    }
    )
    ....
    if (data.add(factory.create(name))) {

    Tom Hawtin
    Tom Hawtin, Apr 20, 2007
    #2
    1. Advertising

  3. Mauro

    CD1 Guest

    Hi Mauro,

    How can you tell the type T has a constructor with a String parameter?
    If you know you'll only use a type (or certain types) in this method,
    try not using generics.

    Cya!

    On Apr 20, 3:39 pm, Mauro <> wrote:
    > HI All,
    > This problem is not new, I read a lot, but I still do not understand
    > if there's a solution or not (shame on me).
    >
    > The problem is: I want to build a generic class that constructs new
    > instances of the type variable.
    > i.e.:
    >
    > public interface IOCElement extends Serializable, ChangeEmitter {
    > public String getName();
    >
    > }
    >
    > public class GenericListModel<T extends IOCElement> extends
    > AbstractListModel
    > implements ComboBoxModel, ChangeListener {
    > static final long serialVersionUID = 1l;
    >
    > private ArrayList<T> tList = null;
    >
    > public GenericListModel() {
    > tList = new ArrayList<T>();
    > }
    >
    > // AbstractListModel implementation
    > public Object getElementAt(int index) { return tList.get(index); }
    > public int getSize() { return tList.size(); }
    > // needed for FreeMarker
    > public ArrayList<T> getTasks() { return tList; }
    > // ComboBoxModel implementation
    > transient private int selectedItem = -1;
    > public Object getSelectedItem() { return (selectedItem>=0)?
    > get(selectedItem): null; }
    > public void setSelectedItem(Object anItem) { if (anItem instanceof
    > IOCElement) { selectedItem = pos(((IOCElement)anItem).getName()); } }
    >
    > // API
    > public T get(int index) { return tList.get(index); }
    > public int add(String name) {
    > int index = 0;
    > if (tList.add(new T(name))) {
    > index = tList.size();
    > tList.get(index-1).addChangeListener(this);
    > selectedItem = -1;
    > fireIntervalAdded(this, index, index);
    > }
    > return index-1;
    > }
    > .... etc. etc.
    >
    > Everything is ok BUT the line that reads:
    > if (tList.add(new T(name))) {
    >
    > I understand that erasures make this difficult for the compiler, but:
    > Is there a way around this (possibly using newInstance(),
    > constructor() or whatever)?
    > Can someone tell me exactly what I should do? (if anything can be
    > done).
    >
    > Thanks in Advance
    > Mauro
    CD1, Apr 20, 2007
    #3
  4. Mauro

    Adam Maass Guest

    "Mauro" <> wrote:
    >
    > This problem is not new, I read a lot, but I still do not understand
    > if there's a solution or not (shame on me).
    >
    > The problem is: I want to build a generic class that constructs new
    > instances of the type variable.
    > i.e.:
    >


    The classical answer is to require a parameter of type Class<T>.

    Then you can keep the Class variable and reflect on it using
    ....newInstance().

    Of course, there's no guarantee that the Class will actually have a
    constructor with the parameters you expect.
    Adam Maass, Apr 21, 2007
    #4
  5. Mauro

    Tom Hawtin Guest

    Adam Maass wrote:
    >
    > The classical answer is to require a parameter of type Class<T>.


    That's the classical answer to a different question...

    > Then you can keep the Class variable and reflect on it using
    > ...newInstance().


    Noooo, not reflection! Class.newInstance is the most evil of them all.

    Tom Hawtin
    Tom Hawtin, Apr 21, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dave Stallard
    Replies:
    37
    Views:
    953
    Roedy Green
    Oct 8, 2003
  2. Juergen Berchtel
    Replies:
    1
    Views:
    5,971
    John C. Bollinger
    May 20, 2005
  3. Collins

    new to generics

    Collins, Nov 6, 2006, in forum: Java
    Replies:
    7
    Views:
    280
    Chris Uppal
    Nov 7, 2006
  4. Soul
    Replies:
    0
    Views:
    505
  5. Replies:
    2
    Views:
    439
    Thomas 'PointedEars' Lahn
    Mar 11, 2008
Loading...

Share This Page