錯誤/異常:java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 的解決方法


1、錯誤/異常圖  

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseDao' defined in class path resource [spring/beans_common.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.oa.common.dao.impl.BaseDao]: Constructor threw exception; nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

 

錯誤/異常描述:反射類型轉換失敗(nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

一開始我以為是baseDao注入失敗/異常,然后我就仔細檢查spring的配置文件(檢查了N遍),發現一點問題都沒有。后來,經過Debug一步一步調試,發現出錯位置:BaseDao()構造器,原代碼:

 1     private Class<T> clazz;
 2 
 3     //反射機制,獲取對應的對象
 4     @SuppressWarnings("unchecked")
 5     public BaseDao() {//構造函數的作用:獲取對應的實體類對象
 6         // this——表示當前類(UserDao)
 7         // this.getClass()——當前運行類的字節碼(UserDao.class)
 8         // this.getClass().getGenericSuperclass()——當前運行類的父類(BaseDao<T>,以為User為例,那就是BaseDao<User>)
 9         Type type = this.getClass().getGenericSuperclass(); // generic 泛型
10         // 強制轉化“參數化類型”
11         ParameterizedType parameterizedType = (ParameterizedType) type;
12         // 參數化類型中可能有多個泛型參數
13         Type[] types = parameterizedType.getActualTypeArguments();
14         // 獲取數據的第一個元素(User.class)
15         clazz = (Class<T>) types[0]; // com.oa.shore.entity.User.class 
16     }

說明:我用的是SSH框架(注解版)。JDK-1.8;Tomcat-7.0.96

我用到的jar包:

    

 

2、解決方法    

加個判斷,即可解決:

 1   private Class<T> clazz;
 2 
 3   //反射機制,獲取對應的對象
 4   @SuppressWarnings("unchecked")
 5   public BaseDao() {//構造函數的作用:獲取對應的實體類對象
 6       // this——表示當前類(UserDao)
 7       // this.getClass()——當前運行類的字節碼(UserDao.class)
 8       // this.getClass().getGenericSuperclass()——當前運行類的父類(BaseDao<T>,以為User為例,那就是BaseDao<User>)
 9       Type type = this.getClass().getGenericSuperclass(); // generic 泛型
10       if(type instanceof ParameterizedType){
11           // 強制轉化“參數化類型”
12           ParameterizedType parameterizedType = (ParameterizedType) type;
13           // 參數化類型中可能有多個泛型參數
14           Type[] types = parameterizedType.getActualTypeArguments();
15           // 獲取數據的第一個元素(User.class)
16           clazz = (Class<T>) types[0]; // com.oa.shore.entity.User.class 
17       }
18   }

說明:如果你的SessionFactory是“手動”的形式交給spring容器注入,那么,上面的問題還是解決不了;想要解決此問題,得 extends HibernateDaoSupport 它,讓spring容器自動去管理/注入,即可解決此問題。可參考以下BaseDao實現類的全部代碼

 1 package com.oa.common.dao.impl;
 2 
 3 import java.lang.reflect.ParameterizedType;
 4 import java.lang.reflect.Type;
 5 import java.util.List;
 6 
 7 import org.hibernate.Query;
 8 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 9 import org.springframework.stereotype.Repository;
10 
11 import com.oa.common.dao.IBaseDao;
12 
13 /**
14  * @author DSHORE/2020-2-6
15  *
16  */
17 @Repository("baseDao")
18 public class BaseDao<T> extends HibernateDaoSupport implements IBaseDao<T>  {
19     /* //此處交給spring自動管理/注入了(extends HibernateDaoSupport)
20     @Autowired
21     private SessionFactory sessionFactory;
22      
23     public void setSessionFactory(SessionFactory sessionFactory) {
24         this.sessionFactory = sessionFactory;
25     }*/
26     
27     private Class<T> clazz;
28 
29     //反射機制,獲取對應的對象
30     @SuppressWarnings("unchecked")
31     public BaseDao() {//構造函數的作用:獲取對應的實體類對象
32         // this——表示當前類(UserDao)
33         // this.getClass()——當前運行類的字節碼(UserDao.class)
34         // this.getClass().getGenericSuperclass()——當前運行類的父類(BaseDao<T>,以為User為例,那就是BaseDao<User>)
35         Type type = this.getClass().getGenericSuperclass(); // generic 泛型
36         if(type instanceof ParameterizedType){
37             // 強制轉化“參數化類型”
38             ParameterizedType parameterizedType = (ParameterizedType) type;
39             // 參數化類型中可能有多個泛型參數
40             Type[] types = parameterizedType.getActualTypeArguments();
41             // 獲取數據的第一個元素(User.class)
42             clazz = (Class<T>) types[0]; // com.oa.shore.entity.User.class 
43         }
44     }
45     
46     @Override //新增
47     public int add(T entity) {
48         return (Integer) getHibernateTemplate().save(entity);
49         //return (Integer) sessionFactory.getCurrentSession().save(entity);
50     }
51 
52     @SuppressWarnings("unchecked")
53     @Override //查詢所有
54     public List<T> listAll() {
55         //Query query = sessionFactory.getCurrentSession().createQuery("from " + clazz.getSimpleName());
56         Query query = getSession().createQuery("from " + clazz.getSimpleName()); //這里用clazz.getName()也行 57         return query.list();
58     }
59 }

測試結果圖:

 

此SSH注解版項目的完整代碼(可參考):https://www.cnblogs.com/dshore123/p/12336358.html

 

 

 

 

 

 

原創作者:DSHORE

作者主頁:http://www.cnblogs.com/dshore123/

原文出自:https://www.cnblogs.com/dshore123/p/12331195.html

版權聲明:歡迎轉載,轉載務必說明出處。(如果本文對您有幫助,可以點擊一下右下角的 推薦,或評論,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM