详细说明java泛型中的协变和逆变,以及extens super,并给出相应的示例
时间: 2023-05-26 07:04:18 浏览: 145
Java泛型中的协变和逆变都是针对类型转换的规定。
协变(covariant):指的是继承链中子类(派生类)类型能够作为父类(基类)类型的一种属性,也就是子类可以作为父类使用的能力。在泛型中,协变的概念可以用来表示如果类型A是类型B的一个子类型,那么泛型类G<A>就可以视作泛型类G<B>的一个子类型。
例子:
```java
// Animal类
public class Animal {}
// Dog类是Animal类的子类
public class Dog extends Animal {}
// 泛型接口List
public interface List<E> {
void add(E e);
E get(int index);
}
// 定义一个方法acceptList,其形参类型为List<? extends Animal>
public static void acceptList(List<? extends Animal> list) {
for (Animal animal : list) {
// ...
}
}
// List类型为List<Dog>
List<Dog> list = new ArrayList<Dog>();
list.add(new Dog());
acceptList(list); // 在这里,我们可以传入一个List<Dog>参数,因为Dog类是Animal类的子类
```
逆变(contravariant):指的是继承链中父类(基类)类型能够作为子类(派生类)类型的一种属性,也就是父类可以作为子类使用的能力。在泛型中,逆变的概念可以用来表示如果类型A是类型B的一个超类型,那么泛型类G<B>就可以视作泛型类G<A>的一个子类型。
例子:
```java
// Animal类
public class Animal {}
// Dog类是Animal类的子类
public class Dog extends Animal {}
// 泛型接口Comparator
public interface Comparator<T> {
int compare(T o1, T o2);
}
// 定义一个方法sortList,其形参类型为List<? super Dog>
public static void sortList(List<? super Dog> list) {
// ...
}
// List类型为List<Animal>
List<Animal> list = new ArrayList<Animal>();
list.add(new Animal());
sortList(list); // 在这里,我们可以传入一个List<Animal>参数,因为Animal类是Dog类的超类型
```
extends和super关键字常常用于定义泛型类型参数的上边界(upper bound)和下边界(lower bound)。extends表示类型参数的上限,超过这个范围就会导致编译错误;super表示类型参数的下限,超过这个范围也会导致编译错误。
例子:
```java
// 泛型类Pair,其类型参数T有上限(用extends)为Comparable<? super T>,表示类型T要么是Comparable<? super T>本身,要么是Comparable<? super T>的子类型
public class Pair<T extends Comparable<? super T>> {
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
public T getFirst() {
return first;
}
public T getSecond() {
return second;
}
public T max() {
return first.compareTo(second) >= 0 ? first : second;
}
}
// Pair类型为Pair<String>
Pair<String> pair = new Pair<String>("hello", "world");
String max = pair.max(); // 在这里,我们可以调用max方法,因为String类实现了Comparable<String>接口
```
阅读全文