<? extends T>上限通配,表示?是T的一个未知子类。
<? super T>下限通配,表示?是T的一个未知父类。
下面来分别讲一下
1. <? extends T> 上限通配
这里?表示一个未知的类,而T是一个具体的类,在实际使用的时候T需要替换成一个具体的类,表示实例化的时候泛型参数要是T的子类。
举个例子
我们有一个水果类
/**
* 水果类
*/
public abstract class Fruit {
public abstract void eat();
}
然后创建两种水果继承水果类Fruit
/**
* 苹果类
*/
public class Apple extends Fruit {
@Override
public void eat() {
System.out.println("我是苹果,我是酸酸甜甜的");
}
}
/**
* 香蕉类
*/
public class Banana extends Fruit {
@Override
public void eat() {
System.out.println("我是香蕉,我是软软的");
}
}
我们还需要一个吃瓜群众
/**
* 吃瓜群众
*/
public class People<T extends Fruit> {
public void eatFruit(T t){
t.eat();
}
}
请注意定义People类的时候我们使用了泛型上限表示<T extends Fruit>
我们创建一个类测试一下
public class Test {
public static void main(String[] args) {
People<Apple> p1 = new People<>();
p1.eatFruit(new Apple());
People<Banana> p2 = new People<>();
p2.eatFruit(new Banana());
}
}
输出结果.png
若此时我们创建一个橙子类,但不继承自Fruit父类
/**
* 橙子类
*/
public class Orange {
public void eat() {
System.out.println("我是橙子,我是酸酸的");
}
}
编译时期就会报错,提示Orange不在范围内,应该要继承Fruit类
编译报错.png
2. <? super T> 下限通配
这里?表示一个未知的类,而T是一个具体的类,在实际使用的时候T需要替换成一个具体的类,表示实例化的时候泛型参数要是T的父类。
例如
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}
这里表示我们调用这个方法时可以传入参数是Integer或者Integer的父类,例如:
public class TestLowerBounded {
public static void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 10; i++) {
list.add(i);
}
}
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
addNumbers(list1);
List<Number> list2 = new ArrayList<>();
addNumbers(list2);
List<Object> list3 = new ArrayList<>();
addNumbers(list3);
List<String> list4 = new ArrayList<>();
//编译错误,因为String不是Integer的父类
//addNumbers(list4);
}
}
Number和Object都是Integer的父类,所以编译通过,而String不是Integer的父类,编译报错。
以上就是泛型上限通配符和下限通配符的作用了,知识点比较小,希望可以一点一点积累,和大家一起进步。
网友评论