如何将Generics应用于不使用类的类型参数的方法

时间:2012-08-28 18:16:00

标签: java generics

我是Java Generics的新手。我正在设计我的DAO层。我正在使用JPA和Spring。我有一个BaseDAO,由所有其他DAO类扩展。

public abstract class BaseDAO<E, Id extends Serializable> implements IBaseDAO<E, Id> {

private Class<E> entityClass;

@PersistenceContext
private EntityManager entityManager;

public EntityManager getEntityManager() {
    return entityManager;
}

@SuppressWarnings("unchecked")
public BaseDAO() {
    ParameterizedType genericSuperclass = (ParameterizedType) getClass()
            .getGenericSuperclass();
    this.entityClass = (Class<E>) genericSuperclass
            .getActualTypeArguments()[0];
}

@Override
public E create(E entity) {
    entityManager.persist(entity);
    return entity;
}

//Some more methods

@Override
public List<?> executeNativeQuery(String queryString,
        Map<String, Object> param) {

//implementation goes here

    return resultList;
}

}

我在添加公共列表时遇到问题executeNativeQuery(String queryString,             映射param)到这个类。因为如果我在扩展BaseDAO的类A中使用此方法,我将必须为基类指定类型参数“E”和“Id”。理想情况下,type参数应该是我们要进行db调用的实体类。但由于此方法是本机查询方法,因此我不使用实体类。我该如何处理这种情况?

编辑: 假设下面是DAO类,它扩展了BaseDAO并使用了executeNativeQuery方法

公共类MyDAO扩展了BaseDAO {

public String myMethod(){

String query="select a1,a2,a3,b4 from A a, B b where a.pk=b.pk";
...
..
List<String> = executeNativeQuery(query, map, String.class);

...
..  
}

}

如果我没有为BaseDAO指定类型参数,我仍会得到以下错误。

java.lang.Class无法在org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)中强制转换为java.lang.reflect.ParameterizedType

应该为BaseDAO传递什么类型参数?

2 个答案:

答案 0 :(得分:3)

您可以执行以下操作。

@Override
public <T> List<T> executeNativeQuery(String queryString,
        Map<String, Object> param, Class<T> clazz) {

//implementation goes here

    return resultList;
}

在第三个参数中,您可以指定要使用的列表的类型。 E. g。 List<SomeEntity> result = executeNativeQuery("query", paramMap, SomeEntity.class)

答案 1 :(得分:0)

正如我所看到的,问题出现在以下行的构造函数中。

ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();

您应该使用getGenericInterfaces()[0],因为BaseDAO类不会从任何内容扩展(因此您获得Object作为父级),但实现IBaseDAO