Java泛型与反思|如何实例化泛型类

时间:2016-05-13 17:10:07

标签: java generics reflection syntax

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

基本上我有这种情况。

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类被假定在工厂的同一个包中(我试图保持它的简单,以便在这里发布)。

在捕获中,由于反射失败,我假设没有Wha​​teverClassDAO所以我想要返回MyDAO<Integer,WhateverClass>,但我无法通过右{{1}那里的参数。我试着传递E作为一个没有运气的论据。我基本上想知道用什么代替?????。

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

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

你应该创建一个泛型方法,并且最好让它返回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) {};
    }         
  }