美文网首页
Java中的Covariance, Contravariance

Java中的Covariance, Contravariance

作者: 天之見證 | 来源:发表于2022-05-05 22:14 被阅读0次

    0. Covariance and Contravariance, Invariant

    三者的定义:

    • Covariance: accept subtypes

    • Contravariance: accept supertypes

    • Invariant:除上面2种情况

    1. 数组

    数组是covariant的

    1.1 T[]可以保存其子类

    Number[] nums = new Number[5];
    nums[0] = new Integer(1); // Ok
    nums[1] = new Double(2.0); // Ok
    

    1.2 当S<=T时, S[]<=T[]

    Integer[] intArr = new Integer[5];
    Number[] numArr = intArr; // Ok
    

    1.3 它的问题

    以下的代码编译期没有问题,但是由于栈污染,在运行时会报错 ArrayStoreException

    numArr[0] = 1.23; // Not ok
    

    2. 范型

    范型是invariant的,这样可以避免运行时的栈污染

    由于范型在运行时由于类型擦除不知道具体类型,所以不能在运行时检测出栈污染,所以范型是invariant,运行时没有类型,没法进行子类,父类的比较

    ArrayList<Integer> intArrList = new ArrayList<>();
    ArrayList<Number> numArrList = intArrList; // Not ok
    ArrayList<Integer> anotherIntArrList = intArrList; // Ok
    

    3. 通配符

    通配符让范型有能力支持covariance和contravariance,例如:

    ArrayList<Integer> intArrList = new ArrayList<>();
    ArrayList<? super Integer> numArrList = intArrList; // Ok
    ArrayList<? extends Integer> inarr = intArrList;  // ok
    
    ArrayList<? super Number> numArrList = intArrList; // Not Ok
    ArrayList<? extends Number> inarr = intArrList;  // ok
    

    Java中表示类型的上界和下界

    下界(Contravariant):

    ? super Integer
    

    上界(Covariant):

    ? extends Integer
    

    4. 副作用

    4.1 Covariant types是read-only

    由于Covariant可以保证我们读取的数据一定是一个什么类型(可以使用它的下界)

    ArrayList<? extends Number>可以保证读出来的肯定可以转成Number类型

    但是写数据的时候不能保证,写入的是正确的类型,因为nums.add()不能保证类型

    4.2 Contravariant types是write-only

    ArrayList<? super Integer>可以保证这个对象接受Integer对象,即我们可以写入Integer,但不能保证我们读出来的一定是个Integer

    5. 应用

    Producer extends, Consumer super

    producer-like的对象可以产出T类型的对象,所以类型可以是 <? extends T>,可以作为函数的返回参数

    consumer-like的对象可以消费T类型的对象,所以类型可以是<? super T>,可以作为函数的入参

    Ref:

    1. https://www.freecodecamp.org/news/understanding-java-generic-types-covariance-and-contravariance-88f4c19763d2/
    2. https://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-are-java-generics-not-implicitly-po/2745301#2745301
    3. Covariance and contravariance (computer science) - Wikipedia

    相关文章

      网友评论

          本文标题:Java中的Covariance, Contravariance

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