Java泛型和反射|如何实例化泛型类



现在是星期五晚上,所以我可能有点慢,但我无法解决我认为很简单的问题。

我基本上有这种情况。

1) 基类MyDAO

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

2) 给定包中的一堆MyDAO具体类实现,比如:

public class TaxonomyDAO extends MyDAO<Integer,Taxonomy>{
    ....
}

每个扩展MyDAO的类基本上都添加了与它们的E元素相关的特定DAO特性。我正在编写一个通用工厂,其目标是如果存在此类,则使用反射来提供WhateverClassDAO的实例,如果不存在,则返回基MyDAO。假设K总是整数。

我写过这样的东西:

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) {};
        }         
    }

该类在给定Class c(比如WhateverClass)的情况下,尝试使用反射来使用参数化构造函数创建WhateverClassDAO的实例。***DAO类被假设在工厂的同一个包中(我试图保持它足够简单,以便在这里发布)。

在catch中,由于反射失败,我假设没有WhateverClassDAO,所以我想返回一个MyDAO<Integer,WhateverClass>,但我无法在那里传递正确的E参数。我试图通过Class<E>作为一个论点,但没有成功。我基本上在想用什么来代替?????。

它超出了范围,但所有这些代码都在Singleton EJB中。

任何帮助,即使是以链接到适当文档的形式,也将不胜感激。

Class也是通用的,您可以从中推断出正确的通用参数:

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

您应该创建一个通用方法,并更好地使其返回dao基类,而不是Object:

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

最新更新