美文网首页
Java泛型

Java泛型

作者: 多关心老人 | 来源:发表于2018-12-10 02:33 被阅读0次
    • java泛型擦除,在.class文件中还是可以拿到泛型信息的
    • java中的类、成员变量和方法参数、返回值等都能从.class中拿到泛型参数,但是局部变量拿不到泛型信息
    • 拿泛型信息需要用field.getGenericType或method.getGenericTypes,如果没有泛型信息会返回field.getType和method.getParameterTypes而不是null
    • 泛型信息返回的结果是Type,Type是个更高层的类,他的子类有Class, ParameterizedType等。如果泛型Type是ParameterizedType,则通过getRawType拿到外层信息和getActualTypes拿到里面的类型Type,注意里面的类型Type有可能还是ParameterizedType,如List<Map<String, Integer>>这种。如果是List<String>这种则rawType就是List,actualType就是String。还有一种是WildcardType,这个是? extends和? super。

    • 泛型是不可协变的,如List<Object>不是List<Integer>的父类,不能通过强转把List<Integer>赋值给List<Object>。
    • 可以通过List<? extends Number> dataList = new ArrayList<BigIntger>() 这种协变赋值,dataList中放的是Number的子类,如果你认为可以向dataList中添加Number及其子类对象那你就大错特错了,dataList中除了null你加入不了任何对象。因为List<? extends Number> dataList告诉你我是一个Number及其子类的List集合,但具体是Number的哪个子类集合你是不知道的,你只知道dataList中的元素都可以转成Number,但是具体是BigInteger还是BigDecimal你是不知道的,List<? extends Number>有可能指向的是List<BigInteger>也有可能指向List<BigDecimal>,你说jdk敢让你往List<? extends Nubmber>集合中加入任何元素吗?除了null以外。
    • List<? super Number> dataList = new ArrayList<>(),这个是说dataList里面放的是Number及其父类对象,假如说Number的父类有Digit和Object,那么List<? super Number>可以指向List<Digit>和List<Object>,这个时候可以向里面插入Digit或Object对象,为了保险起见,插入Number及其子类对象是万无一失的。而dataList.get(0)返回的可能是Number及其子类,也可能是Digit或Object,jdk为了保险起见返回给你的就是Object。
    • java的泛型设计成这样确实让人迷惑,我们可以记住一个PECS规则,provider extends consumer super,提供数据(调get获取数据)的集合用? extends,消费数据(调add往里加数据)的集合用? super。不要试图往? extends里加数据,也不要试图从? super里取数据。可以参考jdk源代码Collections中的一个方法
    public static <T> void copy(List<? super T> dest, List<? extends T> src) {
            int srcSize = src.size();
            if (srcSize > dest.size())
                throw new IndexOutOfBoundsException("Source does not fit in dest");
    
            if (srcSize < COPY_THRESHOLD ||
                (src instanceof RandomAccess && dest instanceof RandomAccess)) {
                for (int i=0; i<srcSize; i++)
                    dest.set(i, src.get(i));
            } else {
                ListIterator<? super T> di=dest.listIterator();
                ListIterator<? extends T> si=src.listIterator();
                for (int i=0; i<srcSize; i++) {
                    di.next();
                    di.set(si.next());
                }
            }
        }
    

    相关文章

      网友评论

          本文标题:Java泛型

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