zoukankan      html  css  js  c++  java
  • 泛型的实质

    泛型可以理解为在类上贴了一个标签,作用是编译器通过标签确定类型。在底层运行时会先执行一个“类型擦除”的操作

    那么有什么方法可以使类跳过泛型检查呢?我们可以使用反射使类在编译的时候越过泛型检查。

    示例代码:

        public static void main(String[] args)throws Exception {
            List<String> list = new ArrayList<>();
            list.add("字符串1");
            list.add("字符串2");
            list.add("字符串3");
            //在list上有泛型限制,限制这个list对象的类型为String
    //        list.add(11);//添加一个Integer类型数据会报编译时错误
            /**
             *        那我们如何在list中添加一个Integer类型的数据呢?
             *        可以使用反射进行添加
             */
            //获取list集合的对象,因为要操作对象,所以直接只用.getClass获取对象的字节码文件
            Class<?> listObject = list.getClass();
            //得到list对象的add方法
            Method listAddMethod = listObject.getDeclaredMethod("add",Object.class);
            //往数组中添加Integer类型数据
            listAddMethod.invoke(list,11);
            listAddMethod.invoke(list,22);
            listAddMethod.invoke(list,33);
            for (Object e : list){
                //字符串1 字符串2 字符串3 11 22 33 ,完成添加
                System.out.print(e + " ");
            }
            /**
             * 解释:因为泛型信息只存在于代码编译阶段,编译器编译完成带有泛型的java程序后,
             * 生成的class文件中与泛型相关的信息就会被擦除,以此使程序执行效率不受影响,这个过程
             * 叫做泛型的类型擦除,也就是说泛型类型和普通类在java虚拟机内是一样的。
             * 在本例中,list<String> 与List<Integer>经过编译的类型擦除后,类型均为java.util.ArrayList
             * 由于编译生成的字节码文件会丢失泛型的类型信息,只要能跳过编译器,就可以往某个泛型
             * 集合中添加其他类型的数据(通过反射获取类的字节码文件,获取这个对象的添加方法)
             * 这也就是我们为什么称java为伪泛型语言
             */
        }
  • 相关阅读:
    数据结构实验之栈与队列四:括号匹配(SDUT 2134)
    从 s 点到 t 点的最短路(简单模板)(迪杰斯特拉)
    畅通工程续(HDU 1874)(简单最短路)
    Til the Cows Come Home ( POJ 2387) (简单最短路 Dijkstra)
    顺序表应用7:最大子段和之分治递归法(SDUT 3664)
    Java面向对象4(P~U)
    House Lawn Kattis
    Jumbled String (Kattis
    队列详解及java实现
    栈详解及java实现
  • 原文地址:https://www.cnblogs.com/huanghuanghui/p/10164218.html
Copyright © 2011-2022 走看看