美文网首页
List里面放int数据

List里面放int数据

作者: 徐如是 | 来源:发表于2018-08-07 17:36 被阅读0次

    我今天被爱学习的同学问到了如何在List<String>里面放一个int的数据

    比如

    List<String> list = new ArrayList<String>();
    int a = 1;
    list.add(a);
    

    这样写肯定报错了。毫无疑问。
    先不管为什么他要给我来一个不合理的问题。先管实现。
    这里我首先考虑到一个事情,泛型是什么,不加泛型的话

    List list = new ArrayList();
    int a = 1;
    String str = "1"
    list.add(a);
    list.add(str);
    

    是不会报错的。
    那么泛型这个到底做了啥?
    深究是不可能的,这辈子都不想去深究。
    但是综合经验来看。
    这是一个语法糖。
    所谓语法糖,只是方便程序员写的,减少异常出现可能性等的一个手段,实际上编译器最后会把语法糖废掉,并用基础的方式去搞
    如果把编译好的自己码.class文件拿去反编译,你会发现

    List<String> list = new ArrayList<String>();
    String a= "1"
    list.add(a);
    

    编译,并反编译,下面是反编译的结果

        List list = new ArrayList();
        String a = "1";
        list.add(a);
    

    是的,<String>被废了,当我添加一个数据获取操作的时候,计算长度

    list.get(0).length();
    

    编译,并反编译,下面是反编译的结果

        ((String)list.get(0)).length();
    

    嗯,原来如此,看到了吧。编译器给我们来了一个(String)的类型转换。
    那么

      List list = new ArrayList();
            String a= "1";
            list.add(a);
            ((String) list.get(0)).length();
    

    这段代码的编译结果和上面那段的一样,也就是少了<String>泛型约束,多了(String)类型转换。稍加思考,你会懂得的。

    所以如何在List<String>里放int呢?
    通过上面的分析,我们可以得出某种结论:用了泛型,经过编译器后,会出现”类型擦除“的现象,并添加强制类型转换的操作。
    那么,如果我自己做类型擦出呢?
    这里有个故事,昨天晚上我想到用反射,嗯,成功了,于是我今天来写文章,但是刚刚写着写着,我,发现,类型擦除,并不需要反射,看代码

        1   List<String> list = new ArrayList<String>();
        2   list.add("str");
        3   List list2 = list;
        4   list2.add(1);
        5   System.out.println(list);
        6   System.out.println((int)((Object)list.get(1))+1);
    

    第一行我声明一个泛型List<String> list
    第二行给list添加一个字符串,目的是做参照
    第三行生么一个无泛型的 List list2 ,并让他=list,注意,这里是地址引用,也就是list2和list指向同一个对象地址空间!(细节百度,不长篇大论)
    第四行给list2放一个int类型的数字
    然后打印list,发现,塞进去了?


    image.png

    并且做数学运算成功了?
    看下字节码反编译:

    List list = new ArrayList();
        list.add("str");
        List list2 = list;
        list2.add(Integer.valueOf(1));
        System.out.println(list);
        System.out.println(((Integer)list.get(1)).intValue() + 1);
    

    他做了啥呀,list的类型擦除,lsit2添加int,list.get(1)的一系列操作。
    再解释就不对了,我本来只想说怎么放的,几行代码的事情,一时兴起就搞一下编译器相关,顺便优化了昨天反射的方法,还不错,所谓的温故而知新。古人诚不欺我!

    理解这个需要
    java语法(写了这么多年)
    懂得jvm内存原理(我一知半解)
    编译器原理(我猜的)
    我的程序员守则(我先管实现,再管你和不合理,傻逼要在List<String>里面放int,这违背了java语言泛型的设计初衷,不过他说这是某教学视频的课后习题)

    相关文章

      网友评论

          本文标题:List里面放int数据

          本文链接:https://www.haomeiwen.com/subject/woyavftx.html