使用反射為泛型集合添加其他類型的數據時遇到的問題


泛型是提供給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;所以才報錯
 


免責聲明!

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



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