通配符解决的问题
通配符是用来解决泛型无法协变的问题的,协变指的就是如果 Student 是 Person 的子类,那么 List 也应该是 List 的子类。但是泛型是不支持这样的父子类关系的。如下代码示例:
class Message<T> { private T message; public T getMessage() { return message; } public void setMessage(T message) { this.message=message; } } public class TestDemo { public static void main(String[] args) { Message<String> message1=new Message<>(); message1.setMessage("哈喽啊"); fun(message1); Message<Integer> message2=new Message<>(); message2.setMessage(10); fun(message2); } public static void fun(Message<String> temp) { System.out.println(temp.getMessage()); } }
如上图所示,会在此处编译报错,这是因为fun函数内的参数类型为String类型,不支持Integer类型。
我们需要的解决方案:可以接收所有的泛型类型,但是又不能够让用户随意修改。这种情况就需要使用通配符"?"来处理。
public class TestDemo { public static void main(String[] args) { Message<String> message1=new Message<>(); message1.setMessage("哈喽啊"); fun(message1); Message<Integer> message2=new Message<>(); message2.setMessage(10); fun(message2); } public static void fun(Message<?> temp) { System.out.println(temp.getMessage()); } }
在"?"的基础上又产生了两个子通配符:
? extends 类:设置泛型上限
? super 类:设置泛型下限
通配符的上界
语法:
<? extends 上界> <? extends Number>//可以传入的实参类型是Number或者Number的子类
class Food { } class Fruit extends Food { } class Apple extends Fruit { } class Banana extends Fruit { } class Message<T> { private T message; public T getMessage() { return message; } public void setMessage(T message) { this.message=message; } } public class Demo1 { public static void main(String[] args) { Message<Apple> message1=new Message<>(); message1.setMessage(new Apple()); fun(message1); Message<Banana> message2=new Message<>(); message2.setMessage(new Banana()); fun(message2); } //这里只要是Fruit或者Fruit的子类即可 public static void fun(Message<? extends Fruit> temp) { /* 这里无法确定 temp 引用的是哪个子类对象 所以无法进行修改 temp.setMessage(new Banana()); temp.setMessage(new Apple()); */ //放的都是Fruit或者Fruit的子类,所以 可以直接使用 Fruit 接收 Fruit fruit = temp.getMessage(); System.out.println(temp.getMessage()); } }
通配符的上界,不能进行写入数据,只能进行读取数据。
通配符的下界
语法:
<? super 下界> <? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型
class Food { } class Fruit extends Food { } class Apple extends Fruit { } class Banana extends Fruit { } class Message<T> { private T message; public T getMessage() { return message; } public void setMessage(T message) { this.message=message; } } public class Demo1 { public static void main(String[] args) { Message<Fruit> message1=new Message<>(); message1.setMessage(new Fruit()); fun(message1); Message<Food> message2=new Message<>(); message2.setMessage(new Food()); fun(message2); } //这里只要是Fruit或者Fruit的父类即可 public static void fun(Message<? super Fruit> temp) { //此时可以修改,添加的是Fruit或者Fruit的子类 temp.setMessage(new Banana()); temp.setMessage(new Apple()); //Fruit fruit=temp.getMessage();不能接收,这里无法确定是哪个父类 System.out.println(temp.getMessage());//只能直接输出 } }
通配符的下界,不能进行读取数据,只能写入数据。


