java.lang.Class无法强制转换为java.lang.reflect.ParameterizedType [英] java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

查看:136
本文介绍了java.lang.Class无法强制转换为java.lang.reflect.ParameterizedType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我长期坚持这个问题。我曾经搜索过这个问题,但没有一个解决方案有效。

I am stuck with this issue for a long time. I searched for this issue for sometime but none of solution worked.

结构:

public interface GenericDAO<T extends Serializable, ID extends Serializable>

@Repository
public class AbstractGenericDAO<T extends Serializable, ID extends Serializable> 
    implements GenericDAO<T, ID> {

   private Class<T> persistentClass;

   @Autowired
   private SessionFactory sessionFactory;

   static Logger LOGGER = Logger.getLogger(AbstractGenericDAO.class);


   @SuppressWarnings("unchecked")
   public AbstractGenericDAO() {
       this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
   }

   /**
    * @param entity
    * @return T
    * @throws DBException
    */
   @SuppressWarnings("unchecked")
   public T saveEntity(T entity) throws DBException {
       return saveEntity(entity, false);
   }

   /**
    * @param entity
    * @param explicitFlush
    * @return T
    * @throws DBException
    */
   @SuppressWarnings("unchecked")
   public T saveEntity(T entity, boolean explicitFlush) throws DBException {
       Session session = getSessionFactory().getCurrentSession();

       try {
           session.save(entity);
           if(explicitFlush) {
               session.flush();
               session.refresh(entity);
           }
       } catch (HibernateException he) {
           String errorMsg = "Could not save entity. Reason: " + he.getMessage();
           LOGGER.error(errorMsg, he);
           throw new DBException(errorMsg, he);
       }

       return entity;
   }

   /* (non-Javadoc)
    * @see com.amazon.fc.receive.dbaccess.dao.GenericDAO#getPersistentClass()
    */
   @SuppressWarnings("unchecked")
   public Class<T> getPersistentClass() {
       return persistentClass;
   }

   /**
    * @return the sessionFactory
    */
   public SessionFactory getSessionFactory() {
       return this.sessionFactory;
   }

   /**
    * @param sessionFactory the sessionFactory to set
    */
   @Autowired
   public void setSessionFactory(SessionFactory sessionFactory) {
       this.sessionFactory = sessionFactory;
   }
}

public interface ShlkActiveWorkflowDAO 
    extends GenericDAO<ShlkActiveWorkflow, Serializable> 

@Repository
public class ShlkActiveWorkflowDAOImpl 
    extends AbstractGenericDAO<ShlkActiveWorkflow, Serializable>
    implements ShlkActiveWorkflowDAO

我也在使用< context:component -scan> 在我的 application-config.xml
+< tx:annotation-driven /> ; 在我的 application-config.xml

I am also using <context:component-scan> in my application-config.xml + <tx:annotation-driven /> in my application-config.xml.

请提供一些有关如何修复此问题。

Please provide some information about how to fix this issue.

Exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'abstractGenericDAO' 

Constructor threw exception; nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:946)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:890)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
    at com.coral.spring.Launcher.<init>(Launcher.java:95)
    at com.coral.spring.Launcher.main(Launcher.java:56)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.workflow.dao.AbstractGenericDAO]: Constructor threw exception; nested exception is     
java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:141)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:72)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:938)
    ... 12 more
Caused by: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    at com.workflow.dao.AbstractGenericDAO.<init>(AbstractGenericDAO.java:43)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:126)
    ... 14 more


推荐答案

删除 @Repository 来自 AbstractGenericDAO 的注释,并将其设为 abstract

Remove @Repository annotation from AbstractGenericDAO and make it abstract:

public abstract class AbstractGenericDAO<T extends Serializable, ID extends Serializable> 
   implements GenericDAO<T, ID>

您的问题出现是因为 @Repository 是一个 @Component 的特化,这意味着Spring将尝试创建 AbstractGenericDAO 实例进行注入。由于 AbstractGenericDAO 超类(对象)不是通用的,因此您将无法向下转换其键入 ParameterizedType ,因此这行代码将失败(与您尝试使用<$手动实例化它时的方式相同) c $ c> new AbstractGenericDAO()):

Your problem occurs because @Repository is a specialization of @Component, which means that Spring will try to create AbstractGenericDAO instances for injection. Since AbstractGenericDAO superclass (Object) is not generic, you will not be able to downcast its Type to ParameterizedType, and so this line of code will fail (in the same way that it would if you tried to instantiate it manually with new AbstractGenericDAO()):

this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

专业类 ShlkActiveWorkflowDAOImpl 仍应注释使用 @Repository 。当spring尝试创建此类的实例时,将发生对 AbstractGenericDAO 构造函数的隐式调用,但这次上面提到的代码行将按预期运行。发生这种情况是因为 getClass()返回 ShlkActiveWorkflowDAOImpl.class 这是泛型 AbstractGenericDAO的子类(所以向下转换为 ParameterizedType 有效)。

The specialized class ShlkActiveWorkflowDAOImpl should still be annotated with @Repository. When spring tries to create a instance of this class a implicit call to AbstractGenericDAO constructor will occur, but this time the line of code mentioned above will run as expected. This happens because getClass() returns ShlkActiveWorkflowDAOImpl.class which is a subclass of the generic AbstractGenericDAO (so the downcast to ParameterizedType works).

由于 ShlkActiveWorkflowDAOImpl extends AbstractGenericDAO< ShlkActiveWorkflow,Serializable> 实际类型 ShlkActiveWorkflow 将在运行时正确反映。这是一种已知的解决方法,可避免将 Class< T> 引用传递给 AbstractGenericDAO 构造函数。

Since ShlkActiveWorkflowDAOImpl extends AbstractGenericDAO<ShlkActiveWorkflow, Serializable> the actual type ShlkActiveWorkflow will be correctly reflected at runtime. This is a known workaround to avoid passing a Class<T> reference to the AbstractGenericDAO constructor.

如果您担心 @Autowired 注释 AbstractGenericDAO ,不要。当你注入一个子类的实例时,Spring会正确连接所有内容。

If you are worried about the @Autowired annotation at AbstractGenericDAO, don't be. Spring will correctly wire everything up when you inject a instance of one of its subclasses.

这篇关于java.lang.Class无法强制转换为java.lang.reflect.ParameterizedType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆