美文网首页
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泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

  • Kotlin 泛型

    说起 kotlin 的泛型,就离不开 java 的泛型,首先来看下 java 的泛型,当然比较熟悉 java 泛型...

  • java泛型中类型擦除的一些思考

    java泛型 java泛型介绍 java泛型的参数只可以代表类,不能代表个别对象。由于java泛型的类型参数之实际...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型

    Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型 在代码进入和离开的边界处,会处理泛型 Java泛型作...

  • JAVA 核心笔记 || [xxx] 泛型

    泛型 JAVA 的参数化类型 称为 泛型 泛型类的设计 Learn12.java 运行

  • 简单回顾Java泛型之-入门介绍

    什么时候开始有了Java泛型?什么是Java泛型?为什么要引入Java泛型?什么时候用到了泛型?可不可以给泛型下一...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • JAVA-泛型

    JAVA-泛型 sschrodinger 2018/11/15 简介 泛型是Java SE 1.5的新特性,泛型的...

网友评论

      本文标题:Java泛型

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