Java反射給泛型集合賦值
泛型
Java泛型簡單描述下:
比如建立一個List集合,我想在裡邊只放Student物件資訊,就需要寫成
List<Student> studentList = new ArrayList();
這個時候List裡面就只能放入Student型別的值,如果強行放入其他型別(比如說Integer)的就會提示錯誤資訊:
java.lang.ClassCastException: java.lang.Integer cannot be cast to com.entity.Student
按照這個結果來看,studentList裡面就只能放入Student型別的值,沒有什麼問題。
然後,奇怪的事情發生了,在公司專案的log裡發現了一個error:
java.lang.ClassCastException: java.lang.Integer cannot be cast to com.entity.Student
原始碼類似於:
Student student = studentList.get(0);
What? 集合建立的時候明明給的泛型是Student啊,這個String是哪蹦出來的。
這個時候又得提出一個概念:
反射
比較全面的解釋:
JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的位元組碼檔案物件。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼檔案對應的Class型別的物件.
一通debug,我發現了這麼一段程式碼(來自於hutools包內的某個方法中,詳細是哪個記不太清了,模仿著寫寫):
public List testReflect(Object arg[], List list) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class<? extends List> aClass = list.getClass();
Method method = aClass.getMethod("add", Object.class);
for (Object o : arg) {
method.invoke(list, o);
}
return list;
}
差不多就這樣子,入參是[1,2,3,4]和studentList,在外邊取list中的值時,發現:
java.lang.ClassCastException: java.lang.Integer cannot be cast to com.entity.Student
這玩意,利用反射獲取了List的add方法,值型別也不判斷,直接給塞進集合裡了。。。。
其實剛開始碰到時,一臉懵的,耗費了很長時間取排查問題,我泛型Student的List,怎麼會出現這種問題,從List
不過後來發現原因之後,感覺其實也不復雜,挺簡單的,還是經驗太少,判斷錯誤能力不行,共勉。
上面的程式碼用的Student類和String、Integer代替,公司內部程式碼就不透露了。