Java 泛型通配符上限和通配符下限
下面来分别讲一下
③.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()); } }
若此时我们创建一个橙子类,但不继承自Fruit父类
/** * 橙子类 */ public class Orange { public void eat() { System.out.println("我是橙子,我是酸酸的"); } }
编译时期就会报错,提示Orange不在范围内,应该要继承Fruit类
编译报错
③.2<? extends T> 上限通配
表示只能接收Number这个类以及这个类的子类的数据类型。(extends表继承,就是这个类下面的东西)再举个例子如下
public static void function(Student<? extends Number> s){ System.out.println("姓名是:"+s.getName()); }
④.1<? 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的父类,编译报错。
④.2<? super T> 下限通配
表示只能接收Number这个类以及这个类的父类的数据类型。(super表父类,超过这个类的东西)再举个例子如下
public static void function(Student<? super Number> s){ System.out.println("姓名是:"+s.getName()); }
以上就是泛型上限通配符和下限通配符的作用了,知识点比较小,希望可以一点一点积累,和大家一起进步。