了解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());
        //不能接收,这里无法确定是哪个父类,父类太多了
    }
}
相关推荐
轻抚酸~3 小时前
小迪23年-32~40——java简单回顾
java·web安全
Sirius Wu5 小时前
Maven环境如何正确配置
java·maven
七七&5565 小时前
2024年08月13日 Go生态洞察:Go 1.23 发布与全面深度解读
开发语言·网络·golang
java坤坤5 小时前
GoLand 项目从 0 到 1:第八天 ——GORM 命名策略陷阱与 Go 项目启动慢问题攻坚
开发语言·后端·golang
元清加油5 小时前
【Golang】:函数和包
服务器·开发语言·网络·后端·网络协议·golang
健康平安的活着6 小时前
java之 junit4单元测试Mockito的使用
java·开发语言·单元测试
Java小白程序员6 小时前
Spring Framework :IoC 容器的原理与实践
java·后端·spring
xuTao6677 小时前
Easy Rules 规则引擎详解
java·easy rules
DjangoJason7 小时前
C++ 仿RabbitMQ实现消息队列项目
开发语言·c++·rabbitmq
m0_480502648 小时前
Rust 入门 KV存储HashMap (十七)
java·开发语言·rust