Java-通过反射了解集合泛型的本质

2020-09-25 269

Java-通过反射了解集合泛型的本质

public class ClassDemo3 { /** * @Author: www.itze.cn * @Date: 2020/9/21 13:47 * @Email: 814565718@qq.com */ public static void main(String[] args) { ArrayList list = new ArrayList(); ArrayList<String> list2 = new ArrayList<>(); list2.add("hello"); //这里泛型约束类型为String,所有这添加 "hello" 没问题 // strings.add(100); 这里添加int类型就会报类型错误 Class<? extends ArrayList> c1 = list.getClass(); Class<? extends ArrayList> c2 = list2.getClass(); System.out.println(c1);// class java.util.ArrayList System.out.println(c2); //class java.util.ArrayList System.out.println(c1 == c2); //true /** * c1 == c2 执行结果为true 说明泛型编译之后是去泛型化的 * 泛型的作用可以理解为;Java中泛型的存在是为了防止输入错误,且只在编译阶段有效 * ************************************************************************** * 上面的例子 list2中,泛型为String,直接添加strings.add(100); 编译报错 * 反射都是发生在编译之后的操作,利用反射的这一作用,证明泛型在编译之后时去泛型化的 * 利用反射绕过编译,实现list2 也能执行add(100) */ try { System.out.println("list2添加100之前元素个数:" + list2.size()); // 1 //使用方法反射 add为list2的方法 Object.class 为参数类型 Method c2Method = c2.getMethod("add", Object.class); c2Method.invoke(list2, 100); System.out.println("list2添加100之后元素个数:" + list2.size()); // 2 /** * 这个时候list2就不能用String类型来遍历了 * 会报java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String * 要用所有共同父类Object */ //遍历 注意这里是Object不是String for (Object str : list2 ) { System.out.println(str); } } catch (Exception e) { e.printStackTrace(); } } }
3 3