泛型是提供給javac編譯器使用的,可以限定集合中的輸入類型,讓編譯器擋住源程序中的非法輸入,編譯器編譯帶類型說明的集合進會去掉“類型”信息,使程序運行效率不受影響。
由於編譯生成的字節碼會去掉泛型的類型信息,只要能跳過編譯器,就可以往某個泛型集合雖加入其它類型的數據。
所以我們可以用反射為泛型集合添加其他類型的數據。
例1:
ArrayList<Integer> arrayList = new ArrayList<Integer>(); arrayList .add(10); arrayList .add(20); arrayList .getClass().getMethod("add",Object.class).invoke(arrayList ,"hbase"); System.out.println(arrayList .get(2));//雖然索引為2的位置存的是String類型,但編譯時編譯器會認為arrayList .get(2)返回的時是Integer類型,但在運行取值時取的仍是 //String類型
輸出:hbase
例2:
ArrayList<String> arrayList = new ArrayList<String>(); arrayList1.add("hadopp"); arrayList1.add("hive"); arrayList1.getClass().getMethod("add",Object.class).invoke(arrayList1,25); System.out.println(arrayList1.get(2));//雖然索引為2的位置存的是Integer類型,但編譯時編譯器會認為arrayList .get(2)返回的時是String類型,但在運行取值時取的仍 //Integer類型
報錯!! Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at com.mobin.generic.GenericTest.main(GenericTest.java:20)
報錯代碼:System.out.println(arrayList1.get(2));
Integer不能轉成String,但例1為會又不報
ClassCastException異常呢?(大家也可以先想想原因是什么再看下面的分析)
下面分析下原因:
出現ClassCastException這個異常可以斷定的是類型的轉換錯誤。
原因就在Syststem.out.println這條語句,


上圖是println()的所有重載方法,除了bool,char,char[],double,float,int,String,long類型外,當傳入的參數是其他類型時被會被當作是Object從而調用println(Object)方法。
在例1中由於arrayList1.get(2)返回的是Integer所以調用的是println(Object)方法,驗證:把鼠標放到println方法上即可.

好,我們再進入println(Object x)的源碼去看看

參數都被自動的轉成了String類型!!!
相當於Object x = arrayList.get(2); //所有對象都屬於Object
String s = String.valueOf(x);
所以不會報錯。
再看第二段代碼的println調用的是println(String x);
同樣進入源碼去看看:

相當於String x = arrayList.get(2); //這里運行時arrayList.get(2)所得的值的類型是Integer,又相當於String x = Integer;所以才報錯