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

2022-10-31 15:55:41 浏览数 (1)

代码语言:javascript复制
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();
        }

    }
}

0 人点赞