• Java之通配符


    在这里插入图片描述

    ⭐️前言⭐️

    🍉博客主页: 🍁【如风暖阳】🍁
    🍉精品Java专栏【JavaSE】【备战蓝桥】、【JavaEE初阶】【MySQL】【数据结构】
    🍉欢迎点赞 👍 收藏留言评论 📝私信必回哟😁

    🍉本文由 【如风暖阳】 原创,首发于 CSDN🙉

    🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言

    🍉博客中涉及源码及博主日常练习代码均已上传码云(gitee)GitHub


    通配符

    🍅通配符解决的问题

    通配符是用来解决泛型无法协变的问题的,协变指的就是如果 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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述
    如上图所示,会在此处编译报错,这是因为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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在"?"的基础上又产生了两个子通配符:

    ? extends 类:设置泛型上限
    ? super 类:设置泛型下限

    🍅通配符的上界

    语法:

    <? extends 上界> 
    <? extends Number>//可以传入的实参类型是Number或者Number的子类
    
    • 1
    • 2

    在这里插入图片描述

    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());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

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

    🍅通配符的下界

    语法:

    <? super 下界> 
    <? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型
    
    • 1
    • 2

    在这里插入图片描述

    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());//只能直接输出
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

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


    ⭐️最后的话⭐️

    总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁

    在这里插入图片描述

  • 相关阅读:
    回溯 -- 21天学习挑战赛第一天
    Python 遍历字典的若干方法
    九、stm32-蓝牙HC_05(接发通信、控制LED亮灭)
    Aviator表达式引擎
    Vue2:组件进阶
    vulnhub靶场之Beelzebub
    数组的拷贝和反转和扩容与缩减
    go-channel
    执行shell脚本插入oracle数据库中文数据乱码
    python11 序列的相关操作
  • 原文地址:https://blog.csdn.net/qq_60856948/article/details/125462019