目录
通配符的作用
先看一段代码
用通配符"?"后,代码变化
结论
通配符上界
通配符下界
对通配符上下界的注释理解及其练习代码
简记: ? 用于在泛型的使用,即为通配符.
在Java中,通配符(wildcard)主要用于泛型编程,用于表示一个不确定的类型。
通配符有三种形式:1.通配符<?> 2.
通配符<? extends T>
3. 通配符<? super T>
通配符的作用
先看一段代码
class Test0 {
public static void main(String[] args) {
System.out.println("===========1.String==============");
Message<String> message1 = new Message<>();
message1.setMessage("fly in the sky!");
fun1(message1);
System.out.println("===========2.Integer=============");
Message<Integer> message2 = new Message<>();
message2.setMessage(99);
fun2(message2);
System.out.println("===========3.Character============");
Message<Character> message3 = new Message<>();
message3.setMessage('s');
func3(message3);
System.out.println("===========4.Short================");
Message<Short> message4 = new Message<>();
message4.setMessage((short) 213);
func4(message4);
System.out.println("===========5.Long=================");
Message<Long> message5 = new Message<>();
message5.setMessage(1024L);
func5(message5);
System.out.println("===========6.Float=================");
Message<Float> message6 = new Message<>();
message6.setMessage(3.1415926f);
func6(message6);
System.out.println("===========7.Double================");
Message<Double> message7 = new Message<>();
message7.setMessage(1024.0213);
func7(message7);
System.out.println("===========8.Boolean===============");
Message<Boolean> message8 = new Message<>();
message8.setMessage(true);
func8(message8);
}
public static void fun1(Message<String> tmp) {
System.out.println(tmp.getMessage());
}
public static void fun2(Message<Integer> tmp) {
System.out.println(tmp.getMessage());
}
public static void func3(Message<Character> tmp) {
System.out.println(tmp.getMessage());
}
public static void func4(Message<Short> tmp) {
System.out.println(tmp.getMessage());
}
public static void func5(Message<Long> tmp) {
System.out.println(tmp.getMessage());
}
public static void func6(Message<Float> tmp) {
System.out.println(tmp.getMessage());
}
public static void func7(Message<Double> tmp) {
System.out.println(tmp.getMessage());
}
public static void func8(Message<Boolean> tmp) {
System.out.println(tmp.getMessage());
}
}
用通配符"?"后,代码变化
class Test1 {
public static void func(Message<?> temp) {
System.out.println(temp.getMessage());
}
public static void main(String[] args) {
System.out.println("===========1.String==============");
Message<String> message1 = new Message<>();
message1.setMessage("fly in the sky!");
func(message1);
System.out.println("===========2.Integer=============");
Message<Integer> message2 = new Message<>();
message2.setMessage(99);
func(message2);
System.out.println("===========3.Character============");
Message<Character> message3 = new Message<>();
message3.setMessage('s');
func(message3);
System.out.println("===========4.Short================");
Message<Short> message4 = new Message<>();
message4.setMessage((short) 213);
func(message4);
System.out.println("===========5.Long=================");
Message<Long> message5 = new Message<>();
message5.setMessage(1024L);
func(message5);
System.out.println("===========6.Float=================");
Message<Float> message6 = new Message<>();
message6.setMessage(3.1415926f);
func(message6);
System.out.println("===========7.Double================");
Message<Double> message7 = new Message<>();
message7.setMessage(1024.0213);
func(message7);
System.out.println("===========8.Boolean===============");
Message<Boolean> message8 = new Message<>();
message8.setMessage(true);
func(message8);
}
}
结论
结论:使用通配符"?"可以接收所有的泛型类型,从而大大减少代码量,
注:虽然通配符 "?" 可以接受任意类型,但正因为如此,由于不确定类型,所以在func方法中无法修改操作
在"?"的基础上又产生了两个子通配符:
? extends 类:设置通配符上限 => 通配符上界
? super 类:设置通配符下限 => 通配符下界
通配符上界
通配符上界
语法:
<? extends 上界>
<? extends String>//可以传入的实参类型是String或者String的子类通配符的上界,不能进行写入数据,只能进行读取数据
通配符下界
通配符下界
语法:
<? super 下界>
<? super Integer>//代表 可以传入的实参的类型是 Integer或者 Integer的父类类型通配符的下界,不能进行读取数据,只能写入数据
class Food {
}
class Fruit extends Food {
}
class Apple extends Fruit {
}
class Banana extends Fruit {
}
对通配符上下界的注释理解及其练习代码
class Food {}
class Fruit extends Food {}
class Apple extends Fruit {}
class Banana extends Fruit {}
class Plate<T> {//设置泛型
private T message;
public T getMessage() {
return message;
}
public void setMessage(T message) {
this.message = message;
}
}
public class Test2 {
public static void main1(String[] args) {
Plate<Apple> applePlate = new Plate<>();
applePlate.setMessage(new Apple());
func1(applePlate);
Plate<Banana> bananaPlate = new Plate<>();
bananaPlate.setMessage(new Banana());
func1(bananaPlate);
}
//通配符的上界
//通配符的上界,不能进行写入数据,只能进行读取数据
public static void func1(Plate<? extends Fruit> tmp) {
//这里仍然不可以进行修改!tmp接收的是Fruit和他的子类,此时存储的元素应该是哪个子类无法确定。
System.out.println(tmp.getMessage());
Fruit b = tmp.getMessage();//向上转型
System.out.println(b);
}
//通配符的下界
//通配符的下界,不能进行读取数据,只能写入数据
public static void main(String[] args) {
Plate<Fruit> fruitPlate = new Plate<>();
fruitPlate.setMessage(new Fruit());
func2(fruitPlate);
Plate<Food> foodPlate = new Plate<>();
foodPlate.setMessage(new Food());
func2(foodPlate);
}
public static void func2(Plate<? super Fruit> tmp) {
//传入参数为Fruit及其父类 ,
//此时可以修改!!添加的是Fruit 或者Fruit的子类
tmp.setMessage(new Apple());
tmp.setMessage(new Fruit());
//不能接收,这里无法确定是哪个父类,父类太多了
}
}