在spring管理的类如何在运行时取得泛型的类型

使用hibernate+spring写的一个BaseDaoSupport。
我的做法是定义一个IBaseDaoSupport接口,该接口里面定义了一些公共的操作数据方法. 提供了两种实现方式,一个是按照hibernate自己的实现方式,一个是继承了spring的hibernateDaoSupport,并提供了自己的实现方法.这两个方法都要实现IBaseDaoSupport接口,然后有一个BaseDaoSupport类,该类也要实现IBaseDaoSupport接口,并在里面定义IBaseDaoSupport 类型的成员属性而且提供getter和setter方法,用来在spring中注入到底需要的是那种实现方式.
package com.clear.dao;

import java.io.Serializable;
import java.util.List;

/**

  • 该接口用于实现基本的数据操作
  • @author Administrator
    *
    */
    public interface IBaseDaoSupport {

    /**

    • 该方法用于添加一个实体
    • @param entity
    • @return */ public Boolean isSaveEntity(T entity);

    /**

    • 该方法用于修改一个实体
    • @param entity
    • @return */ public Boolean isUpdateEntity(T entity);

    /**

    • 该方法用于删除一个实体
    • @param id
    • @return */ public Boolean isDeleteEntity(K id);

    /**

    • 根据ID查询一个实体
    • @param id
    • @return */ public T findEntityById(K id);

    /**

    • 查询所有
    • @return */ public List findEntityAll();

    /**

    • 根据查询语句和参数查询
    • @param ql
    • @param params
    • @return */ public List findEntityByQueryLanguage(String queryString, Object... params);

    public List findEntityBySQLQuery(String sql,Object... params);
    }

package com.clear.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.clear.pojo.Trade;

/**

  • 该类用于实现Spring支持下的数据操作方式
  • @author Yanwei
  • @param
  • ID的泛型
  • @param
  •        实体的泛型
    

    */
    public class BaseDaoSupportBySpring extends
    HibernateDaoSupport implements IBaseDaoSupport {

    @SuppressWarnings("unchecked")
    public List findEntityAll() {
    return getHibernateTemplate().loadAll(entityClass());
    }

    @SuppressWarnings("unchecked")
    public T findEntityById(K id) {
    return (T) getHibernateTemplate().get(entityClass(), id);
    }

    @SuppressWarnings("unchecked")
    public List findEntityByQueryLanguage(String queryString,
    Object... params) {
    return getHibernateTemplate().find(queryString, params);
    }

    public Boolean isDeleteEntity(K id) {
    Boolean flag = false;
    try {
    T entity = findEntityById(id);
    getHibernateTemplate().delete(entity);
    flag = true;
    } catch (Exception e) {
    e.printStackTrace();
    }
    return flag;
    }

    public Boolean isSaveEntity(T entity) {
    Boolean flag = false;
    try {
    getHibernateTemplate().save(entity);
    flag = true;
    } catch (Exception e) {
    e.printStackTrace();
    }
    return flag;
    }

    public Boolean isUpdateEntity(T entity) {
    Boolean flag = false;
    try {
    getHibernateTemplate().update(entity);
    flag = true;
    } catch (Exception e) {
    e.printStackTrace();
    }
    return flag;
    }

     //用于拿到运行时泛型的类型
    

    @SuppressWarnings("unchecked")
    public Class entityClass() {
    return (Class) ((ParameterizedType) BaseDaoSupportBySpring.class
    .getGenericSuperclass()).getActualTypeArguments()[1];
    }

    @SuppressWarnings("unchecked")
    public List findEntityBySQLQuery(final String sql,
    final Object... params) {

    List<T> list = getHibernateTemplate().executeFind(
            new HibernateCallback() {
                public Object doInHibernate(Session session)
                        throws HibernateException, SQLException {
                    SQLQuery sqlQuery = session.createSQLQuery(sql).addEntity(Trade.class);
                    if (params != null && params.length != 0) {
                        for (int i = 0; i < params.length; i++) {
                            System.out.println(params[i]);
                            sqlQuery.setParameter(i, params[i]);
                        }
                    }
                    return sqlQuery.list();
                }
            });
    System.out.println(list.size());
    return list;
    

    }

}

package com.clear.dao;

import java.io.Serializable;
import java.util.List;

public class BaseDaoSupport implements
IBaseDaoSupport {

private IBaseDaoSupport<K, T> baseDaoSupport;

public IBaseDaoSupport<K, T> getBaseDaoSupport() {
    return baseDaoSupport;
}

public void setBaseDaoSupport(IBaseDaoSupport<K, T> baseDaoSupport) {
    this.baseDaoSupport = baseDaoSupport;
}

public List<T> findEntityAll() {
    return baseDaoSupport.findEntityAll();
}

public T findEntityById(K id) {
    return baseDaoSupport.findEntityById(id);
}

public List<T> findEntityByQueryLanguage(String ql, Object... params) {
    return baseDaoSupport.findEntityByQueryLanguage(ql, params);
}

public Boolean isDeleteEntity(K id) {
    return baseDaoSupport.isDeleteEntity(id);
}

public Boolean isSaveEntity(T entity) {
    return baseDaoSupport.isSaveEntity(entity);
}

public Boolean isUpdateEntity(T entity) {
    return baseDaoSupport.isUpdateEntity(entity);
}

public List<T> findEntityBySQLQuery(String sql, Object... params) {
    return baseDaoSupport.findEntityBySQLQuery(sql, params);
}

}

我在spring里面注入的是BaseDaoSupportBySpring类,在BaseDaoSupportBySpring类中使用entityClass却拿不到泛型的类信息,如果直接让其余的dao实现类继承BaseDaoSupportBySpring是可以拿到的,问题是现在我使用的是依赖注入.....求解决方案

[code="java"]
//用于拿到运行时泛型的类型
@SuppressWarnings("unchecked")
public Class entityClass() {
return (Class) ((ParameterizedType) BaseDaoSupportBySpring.class
.getGenericSuperclass()).getActualTypeArguments()[1];
}
[/code]

看看你的代码,你用了getGenericSuperclass(),这个函数的意思就是获得Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。如果是继承了这个
BaseDaoSupportBySpring的子类,你是需要声明K和T的,那么,这就是位于声明一侧的,源码里写了什么到运行时就能看到什么,如果你像用BaseDaoSupportBySpring直接获得泛型,那么,是位于使用一侧的,源码里写什么到运行时都没了。

这样解释你懂了么?

想对带有未绑定的泛型变量的泛型类型获取其实际类型是不现实的,因为class文件里根本没记录实际类型的信息。觉得这句话太拗口的话用例子来理解:要想对java.util.List获取E的实际类型是不现实的,因为List.class文件里只记录了E,却没记录使用 List时E的实际类型。

具体你可以去膜拜[url=http://rednaxelafx.iteye.com/blog/586212]这个帖子[/url]

实现不了。和Java泛型机制有关的。Java是使用的擦除来实现泛型的。就是说编译完之后,虚拟机都不知道是什么具体类型。。。。所以反射也是反射不出来的。

[code="java"]@SuppressWarnings("unchecked")
public Class entityClass() {
return (Class) ((ParameterizedType) BaseDaoSupportBySpring.class.getGenericSuperclass()).getActualTypeArguments()[1];
} [/code]
改成:
[code="java"]@SuppressWarnings("unchecked")
public Class entityClass() {
return (Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
} [/code]
试试。