Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

generics + new = problem

Thread view: 
Mauro - 20 Apr 2007 19:39 GMT
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
Tom Hawtin - 20 Apr 2007 20:00 GMT
> 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
CD1 - 20 Apr 2007 23:08 GMT
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!

> HI All,
> This problem is not new, I read a lot, but I still do not understand
[quoted text clipped - 57 lines]
> Thanks in Advance
> Mauro
Adam Maass - 21 Apr 2007 06:22 GMT
> 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.
Tom Hawtin - 21 Apr 2007 13:56 GMT
> 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


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.