<
Java泛型 通配符 协变 extends 和 逆变 super
>
上一篇

接口的泛型
下一篇

Pattern

Java 泛型

定义

逆变与协变用来描述类型转换(type transformation)后的继承关系,其定义:如果A、B表示类型,f(⋅)表示类型转换,≤表示继承关系(比如,A≤B表示A是由B派生出来的子类)

f(⋅)是逆变(contravariant)的,当A≤B时有f(B)≤f(A)成立;
f(⋅)是协变(covariant)的,当A≤B时有f(A)≤f(B)成立;
f(⋅)是不变(invariant)的,当A≤B时上述两个式子均不成立,即f(A)与f(B)相互之间没有继承关系

协变(用于生成者,即只能作为输出)

<? extends> 实现了泛型的协变

public void process(List<? extends Number> list) {
    for (Number number : list) {
        System.out.println(number);
    }
}

? 是子类,协变同时固定上边界

逆变(用于消费者,即只能作为输入)

<? super> 实现了泛型的逆变

public void addToList(List<? super Integer> list) {
    list.add(1);
    list.add(1.2f);
}

? 是父类,逆变同时固定下边界

上限、下限边界

public <T extends Number> void printNumber(T number) {
    System.out.println(number);
}

// 使用
printNumber(42); // 整数
printNumber(3.14); // 浮点数

这里使用 T extends NumberT 不是 ?

不能直接支持,所以要用逆变的通配符 ?

使用时机:

《Effective Java》中提到: producer-extends, consumer-super.

Kotlin 泛型

// 使用 printNumber(42) // 输出: 42 printNumber(3.14) // 输出: 3.14 ```

Top
Foot