⭐️前言⭐️
🍉博客主页: 🍁【如风暖阳】🍁
🍉精品Java专栏【JavaSE】、【备战蓝桥】、【JavaEE初阶】、【MySQL】、【数据结构】
🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁🍉本文由 【如风暖阳】 原创,首发于 CSDN🙉
🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言
通配符是用来解决泛型无法协变的问题的,协变指的就是如果 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());//只能直接输出
}
}
通配符的下界,不能进行读取数据,只能写入数据。
⭐️最后的话⭐️
总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁