分享

跳过编译器,获取泛型参数的实际类型

 hh3755 2014-08-28
  1. import java.lang.reflect.Method;  
  2. import java.lang.reflect.ParameterizedType;  
  3. import java.lang.reflect.Type;  
  4. import java.util.ArrayList;  
  5. import java.util.Date;  
  6. import java.util.List;  
  7. import java.util.Vector;  
  8.   
  9. public class GenericTest {  
  10.       
  11.     public static void main(String[] args) throws Exception {  
  12.         //泛型类型是给编译器看的,编译成class字节码文件后会丢弃类型信息,所以通过反射是无法知道泛型所存储的实际类型的  
  13.         List<String> list = new ArrayList<String>();  
  14.         list.add("java");  
  15.         //collection.add(20);   //编译报错,因为编译期间严格检查泛型的实际数据类型    
  16.         //由上结论可知,既然编译成class文件后不会保存类型信息,那么是不是就可以通过反射的方式存储任意类型的数据呢?  
  17.         //示例:通过反射在collection中存储除String以外的数据  
  18.         list.getClass().getMethod("add", Object.class).invoke(list,5);  
  19.         list.getClass().getMethod("add", Object.class).invoke(list, new Date());  
  20.         System.out.println(list.size());    //结果是3  
  21.         //用下面的方式去获取元素会报ClassCaseException,因为List中第1和第2条记录都不是String类型,所以取出来的时候会报类型转换异常  
  22.         //System.out.println(list.get(1));  
  23.         //说明:上面示例只想说明,JAVA中的泛型是提供给编译器检查使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会丢弃“类型”信息,使用程序运行效率不受影响  
  24.           
  25.         //由于无法在运行期间获取某个带类型的集合属性的实际类型,但可以获得方法参数列表中泛型参数的实际类型  
  26.         Method method = GenericTest.class.getMethod("getGenericActualType", List.class,Vector.class);  
  27.         Type[] types = method.getGenericParameterTypes();  
  28.         for(int i = 0; i < types.length; i++) {  
  29.             ParameterizedType pt = (ParameterizedType) types[i];  
  30.             System.out.print("泛型原始类型: " + pt.getRawType() + "\t");  
  31.             System.out.println("泛型实际类型: " + pt.getActualTypeArguments()[0]);  
  32.         }  
  33.     }  
  34.       
  35.     /* 
  36.      * 获得泛型参数的原始类型,示例方法 
  37.      */  
  38.     public static void getGenericActualType(List<Date> list,Vector<String> vector) {  
  39.           
  40.     }  
  41. }  

通过反编译工具获取GenericTest.class的源代码:

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多