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();
}

}
}