通过Class,Method来认识泛型的本质
package com.reflect; import java.lang.reflect.Method; import java.util.ArrayList; public class MethodDemo2 { public static void main(String[] args) throws Exception { ArrayList list=new ArrayList(); ArrayList<String> list1=new ArrayList<String>(); list1.add("hello"); // list1.add(10);//会因为10不是String类型而出错 Class c1=list.getClass(); Class c2=list1.getClass(); System.out.println(c1==c2); //反射的操作都是编译之后的操作 /* * C1==C2结果返回true,说明编译后集合的泛型是去泛型化的 * Java中,集合的泛型,是防止错误输入的,只在编译阶段有效 * 绕过编译就无效了 * 验证:我们可以通过方法的反射来操作,绕过编译 * */ Method m=c1.getMethod("add", Object.class); m.invoke(list1, 1); System.out.println(list1.size()); System.out.println(list1); //此时不能用这种方式遍历了,因为之前已经插入了int类型的,这样会转化为String类型,会转换错误 for(String str:list1) { System.out.println(str); } } }
运行结果:
分析上诉结果:
1,list和list1都能add加入集合String类型变量,但是list1由于使用了泛型,所以限定只能加入String类型的,而不能加入Int类型的,但是list没有使用泛型,所以
可以加入任意类型变量。使用泛型的作用就是为了防止输入了错误类型的变量。
2,list1不能加入int类型的变量,是因为编译时候,进行了校验,但是反射是在编译后进行的操作,因此可以绕过编译
3,因为c1==c2,说明list1和list是同一种类类型,都是ArrayList类的类类型。
4,因为泛型绕过了编译,所以使用泛型调用方法的时候,即使使用的是list1集合对象,依然可以插入int类型的变量。
5,list1对象插入了int类型的变量后,不能使用foreach方式输出了,因为此时是通过编译的方式,需要进行int到String类型的转型,显然会报错。