elbuild elbuild - 6 months ago 24
Java Question

Java Generics and Reflection | How to instantiate a generic class

it's friday evening so I may be a little slow but I can't figure out to solve what i thought it was a simple question.

I have basically this situation.

1) a base class MyDAO

public abstract class MyDAO<K, E> implements DAO<K, E>
{
....
}


2) a bunch of MyDAO concrete class implementation in a given package, say:

public class TaxonomyDAO extends MyDAO<Integer,Taxonomy>{

....
}


Every class extending MyDAO basically add specific DAO features relevanto to their E element. I'm writing a generic factory whose goal is to use reflection to provide an instance of WhateverClassDAO if this class exists, and to return a base MyDAO if not. Let's assume K is always Integer.

I've written something like this:

public Object getDAOForEntity(Class c)
{
createEmfa();

try {
Class eDao = Class.forName(getClass().getPackage().getName()+c.getSimpleName()+"DAO");
Constructor<?> cons = eDao.getConstructor(EntityManagerFactory.class);
return cons.newInstance(emfa);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
return new MyDAO<Integer,?????>(emfa) {};

}
}


This class, given a
Class c
(say
WhateverClass
) try to use reflections to create an instance of
WhateverClassDAO
using a parametrized constructor. The
***DAO
classes are assumed to be in the same package of the factory (I tried to keep it simple enough to be posted here).

In the catch, since the reflection failed I assume there's no WhateverClassDAO so I'd like to return a
MyDAO<Integer,WhateverClass>
but I'm not able to pass the right
E
argument there. I tried passing
Class<E>
as an argument with no luck. I'm basically wondering what to substitute to ?????.

It's out of scope, but all this code is inside a Singleton EJB.

Any help, even in form of a link to proper documentation will be much appreciated.

Answer

Class Class is also generic and you can infer the correct generic parameter from it:

public <E> Object getDAOForEntity(Class<E> c) {
    try {
        // ...
    } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
        return new MyDAO<Integer,E>(emfa) {};
    }
}
Comments