Java泛型

  • 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>这种。如果是List这种则rawType就是List,actualType就是String。还有一种是WildcardType,这个是? extends和? super。

  • 泛型是不可协变的,如List不是List的父类,不能通过强转把List赋值给List
  • 可以通过List dataList = new ArrayList() 这种协变赋值,dataList中放的是Number的子类,如果你认为可以向dataList中添加Number及其子类对象那你就大错特错了,dataList中除了null你加入不了任何对象。因为List dataList告诉你我是一个Number及其子类的List集合,但具体是Number的哪个子类集合你是不知道的,你只知道dataList中的元素都可以转成Number,但是具体是BigInteger还是BigDecimal你是不知道的,List有可能指向的是List也有可能指向List,你说jdk敢让你往List集合中加入任何元素吗?除了null以外。
  • List dataList = new ArrayList<>(),这个是说dataList里面放的是Number及其父类对象,假如说Number的父类有Digit和Object,那么List可以指向List和List,这个时候可以向里面插入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  void copy(List dest, List 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 di=dest.listIterator();
                ListIterator si=src.listIterator();
                for (int i=0; i

    你可能感兴趣的:(Java泛型)