泛型的边界和通配符?,还有型变

泛型的边界和通配符?,还有型变

泛型没有继承性

例子:List<Object> list = new ArrayList<String>();会出现编译错误

边界和通配符?

规定泛型的上限

<? extends AA>:支持 AA 或者 AA 子类

规定泛型的下限

<? super AA>:支持 AA 类以及 AA 类的父类,不限于直接父类 比如Object顶级父类也支持

通配符?

<?>任意的泛型类型都可以接受

Java泛型的型变

协变(Covariant)

协变是指在类型转换过程中,类型参数能够按照继承关系向上转型。具体地说,在使用泛型类或接口时,如果类型参数A是类型参数B的子类,则可以将泛型类型Foo<A>视为Foo<B>的子类型。

class Animal {}
class Dog extends Animal {}

class Foo<T> {}
Foo<Animal> foo1 = new Foo<Animal>();
Foo<Dog> foo2 = new Foo<Dog>();
// Foo<Dog> 是 Foo<Animal> 的子类型
Foo<Animal> foo3 = foo2;

在上述代码中,类 Dog 继承自类 Animal,类 Foo 是一个泛型类。Foo<Animal>Foo<Dog> 是不同的类型,但是由于 DogAnimal 的子类,因此我们可以将 Foo<Dog> 赋值给 Foo<Animal>,即 Foo<Dog>Foo<Animal> 的子类型。

逆变(Contravariant)

逆变是指在类型转换过程中,类型参数能够按照继承关系向下转型。具体地说,在使用泛型类或接口时,如果类型参数A是类型参数B的超类,则可以将泛型类型Foo<B>视为Foo<A>的超类型。

class Animal {}
class Dog extends Animal {}

interface Bar<T> {}
class BarImpl<T> implements Bar<T> {}

Bar<Dog> bar1 = new BarImpl<Dog>();
Bar<Animal> bar2 = new BarImpl<Animal>();
// Bar<Animal> 是 Bar<Dog> 的超类型
Bar<Dog> bar3 = (Bar<Dog>) bar2;

在上述代码中,类 Dog 继承自类 Animal,接口 Bar 是一个泛型接口,BarImpl 是实现了 Bar 接口的泛型类。Bar<Dog>Bar<Animal> 是不同的类型,但是由于 DogAnimal 的子类,因此我们可以将 Bar<Animal> 强制转换为 Bar<Dog>,即 Bar<Animal>Bar<Dog> 的超类型。

不变(Invariant)

不变是指在类型转换过程中,类型参数无法转换成其它类型参数。具体地说,在使用泛型类或接口时,如果类型参数A和类型参数B没有继承关系,那么泛型类型 Foo<A>Foo<B> 是不兼容的。

List<Animal> animals = new ArrayList<>();
List<Cat> cats = new ArrayList<>();

animals = cats; //编译错误,List<Animal>和List<Cat>之间不存在子类型关系

综合案例

import java.util.ArrayList;
import java.util.List;

/**
 * @author 安然的尾巴
 * @version 1.0
 */
public class Test {
    public static void main(String[] args){
        //泛型没有继承性
        //List<Object> list = new ArrayList<String>();

        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<AA> list3 = new ArrayList<>();
        List<BB> list4 = new ArrayList<>();
        List<CC> list5 = new ArrayList<>();
    }
    // ? extends AA 表示 支持 AA 或者 AA 子类
    //规定了泛型的上限
    public static void print1(List<? extends AA> c) {
        for (Object object : c) {
            System.out.println(object);
        }
    }
    //说明: List<?> 表示 任意的泛型类型都可以接受
    public static void print2(List<?> c) {
        for (Object object : c) { // 通配符,取出时,就是 Object
            System.out.println(object);
        }
    }
    // ? super 子类类名 AA:支持 AA 类以及 AA 类的父类,不限于直接父类 比如Object顶级父类也支持
    //规定了泛型的下限
    public static void print3(List<? super AA> c) {
        for (Object object : c) {
            System.out.println(object);
        }
    }
}

class AA{}
class BB extends AA{}
class CC extends BB{}