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

|