了解java中的通配符“?“

目录

通配符的作用

先看一段代码

用通配符"?"后,代码变化

结论

通配符上界

通配符下界

对通配符上下界的注释理解及其练习代码


简记: ? 用于在泛型的使用,即为通配符.
在Java中,通配符(wildcard)主要用于泛型编程,用于表示一个不确定的类型。
通配符有三种形式:1.通配符<?> 2.通配符<? extends T> 3. 通配符<? super T>

通配符的作用

先看一段代码

java 复制代码
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());

    }
}

用通配符"?"后,代码变化

java 复制代码
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的父类类型

通配符的下界,不能进行读取数据,只能写入数据

java 复制代码
class Food {
}

class Fruit extends Food {
}

class Apple extends Fruit {
}

class Banana extends Fruit {
}

对通配符上下界的注释理解及其练习代码

java 复制代码
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());
        //不能接收,这里无法确定是哪个父类,父类太多了
    }
}
相关推荐
CV大法好1 分钟前
刘铁猛C#入门 027 抽象和开闭原则
开发语言·c#
飞滕人生TYF4 分钟前
位运算实现加法 的过程中 保证最终进位为 0 详解
java·位运算
七侠镇莫尛貝大侠20236 分钟前
C:mbedtls库实现https双向认证连接示例_七侠镇莫尛貝大侠20241122
c语言·开发语言·https
数据小爬虫@9 分钟前
利用Python爬虫获取淘宝商品评论:实战案例分析
开发语言·爬虫·python
情勤坊16 分钟前
JAVA实现将PDF转换成word文档
java·pdf·word
苹果酱056717 分钟前
springcloud-网关路由gateway
java·开发语言·spring boot·mysql·中间件
武子康24 分钟前
Java-08 深入浅出 MyBatis - 多对多模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据库·sql·mybatis
摇滚侠31 分钟前
java http body的格式 ‌application/x-www-form-urlencoded‌不支持文件上传
java·开发语言·http
檀越剑指大厂41 分钟前
【Python系列】 Base64 编码:使用`base64`模块
开发语言·python