问题:
@Component
public class BaseDao<T extends BaseEntity> extends AbstractHibernateDao<T> {
}
异常:Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.jlpay.promise.dao.BaseDao]: Constructor threw exception; nested exception is java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
原因:
解析:
类似于本例中的构造方法,在方法中,需要得到BaseDaoImpl中的泛型,则先将通过this.getClass()方法获取BaseDaoImpl,然后转换为ParameterizedType类(参见末尾附言部分),然后通过ParameterizedType.getActualTypeArguments();方法可以得到<>中的所有泛型类型,但是如果将BaseDaoImpl在applicationContext.xml文件中创建bean,然后以此获取BaseDaoImpl对象进行使用,如图:
则运行时会报如下错误:
ERROR:Class类型不能转换为ParameterizedType类型
疑问:
BaseDaoImpl不是泛型嘛,为什么不能转换为ParameterizedType类型。
原因:
Spring不支持带泛型的类创建对象,因此,当Spring为BaseDaoImpl创建对象时,只把BaseDaoImpl当做BaseDaoImpl进行创建,因此this.getClass().getGenericSuperclass()返回的是class类型,而不是ParameterizedType,所以也就无法从Class类型转换为ParameterizedType类型。
附言:
ParameterizedType就是Java中的泛型,属于Type的子类。
ParameterizedType.getActualTypeArguments(),(Actual:真实的,目前的,实际的;Arguments:参数)字面翻译为:得到真实的类型参数,即泛型对应的真实类。