了解java中的通配符“?“

news2024/12/22 23:14:11

目录

通配符的作用

        先看一段代码

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

        结论

通配符上界 

通配符下界

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


简记: ?  用于在泛型的使用,即为通配符.
在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());
        //不能接收,这里无法确定是哪个父类,父类太多了
    }
}

  
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/948906.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

11.物联网lwip,网卡原理

一。LWIP协议栈内存管理 1.LWIP内存管理方案 &#xff08;1&#xff09;堆heap 1.灰色为已使用内存 2.黑色为未使用内存 3.紫色为使用后内存 按照某种算法&#xff0c;把数据放在内存块中 &#xff08;2&#xff09;池pool 设置内存池&#xff0c;设置成大小相同的内存块。 2…

想报考pmp,一定得经过培训机构吗?

想要申请PMP考试&#xff0c;必须具备35个学时的PMBOK项目管理学习或培训经验。这是报考的首要条件。 所有符合条件的机构必须具备“PMI”和“中国国际基金会人才交流中心”的授权资质之一即可 首先&#xff0c;在进行英文报名时&#xff0c;需要提供并填写35学时的培训经历。…

WordPress(2)主题安装-菜单-菜单图标

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、上传你的主题文件启用我的是 LoliMeow二、主题设置1.小工具中设置即可在网站右侧显示2.在文章中新建分类用做菜单3.也可在文字的前面添加图标[图标库](http://fa.fangguokeji.cn/)前言 提…

Visual Studio 2022的MFC框架——AfxWinMain全局对象和InitInstance函数

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来重新审视一下Visual Studio 2022下开发工具的MFC框架知识。 在看这篇帖子前&#xff0c;请先看我的另一篇帖子《Visual Studio 2022的MFC框架——应用程序向导》。 当程序调用了CWinApp类的构造…

shell常用脚本

1、Java项目重启脚本 #!/bin/bash# 定义一个函数来结束进程和启动新进程 function restart(){JAR_NAME$1 # jar包LOG_NAME$2 # 日志JVM_ARGS$3 # jvm 参数PID$(ps -ef | grep java | grep ${JAR_NAME} | awk { print $2 })if [[ ! -z "$PID" ]]; thenecho "…

LeetCode(力扣)700. 二叉搜索树中的搜索Python

LeetCode20. 有效的括号 题目链接代码 题目链接 https://leetcode.cn/problems/search-in-a-binary-search-tree/ 代码 递归法 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val #…

进度猫:如何做好项目进度管理?有几点建议

项目目进度管理是在项目实施过程中&#xff0c;对各阶段的进展和项目最终完成的期限进行的管理。目的是保证项目能在满足其时间的约束条件的前提下实现项目的总体目标。 因此为了保证项目能够按时完成&#xff0c;需要制订详尽的可操作性的项目进度管理计划&#xff0c;才可以…

MySQL数据库备份及恢复

数据备份的重要性 1、备份的主要目的是灾难恢复 2、在生产环境中&#xff0c;数据的安全性至关重要 3、任何数据的丢失都可能产生严重的后果 4、造成数据丢失的原因 备份类型(重点) 1、物理备份 数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物…

【App端】uni-app使用百度地图api和echarts省市地图下钻

目录 前言方案一&#xff1a;echarts百度地图获取百度地图AK安装echarts和引入百度地图api完整使用代码 方案二&#xff1a;echarts地图和柱状图变形动画实现思路完整使用代码 方案三&#xff1a;中国地图和各省市地图下钻实现思路完整使用代码 前言 近期的app项目中想加一个功…

QGIS-计算几何内部点(一定在几何内)

在提取几何图像的中心点相关的X Y时&#xff0c;我们往往希望提取的点在几何内部&#xff0c;因为对于不规则图形而言&#xff0c;特别是凹几何&#xff0c;提取的点可能在图形外&#xff0c;QGIS中提供了相关的函数用于提取点中心点&#xff1a; 打开图形的属性列表&#xff…

Springboot2.0 上传图片 jar包导出启动(第二章)

目录 一&#xff0c;目录文件结构讲解二&#xff0c;文件上传实战三&#xff0c;jar包方式运行web项目的文件上传和访问处理&#xff08;核心知识&#xff09;最后 一&#xff0c;目录文件结构讲解 简介&#xff1a;讲解SpringBoot目录文件结构和官方推荐的目录规范 1、目录讲解…

行业毒瘤还是长久需求?无代码编程会是趋势吗?

无代码和低代码都是这几年才诞生、但受到不少关注的新名词。无代码和低代码的发展前景如何&#xff1f;是一时兴起还是长久需求&#xff0c;是不是行业毒瘤&#xff0c;种种讨论络绎不绝。 无代码开发平台&#xff08;NCDP&#xff0c;No Code Development Platform&#xff09…

Java从入门到精通(五)· 内部类,枚举,泛型

Java从入门到精通&#xff08;五&#xff09; 内部类&#xff0c;枚举&#xff0c;泛型 一 内部类 1.概述 简单来说&#xff0c;如果一个类定义在另一个类的内部&#xff0c;这个类就是内部类。 使用场景&#xff1a;当一个类的内部&#xff0c;包含了一个完整的事务&#…

常见的软件测试模型

目录 1、瀑布模型 2、V模型 3、W模型 4、H模型 5、X模型 1、瀑布模型 瀑布模型是一种线性的、顺序的软件开发模型 上一阶段的输出结果作为下一阶段的输入 优点&#xff1a; &#xff08;1&#xff09;为项目提供了按阶段划分的检查点。 &#xff08;2&#xff09;当前一阶段…

【校招VIP】产品面试之面试官的真实意图

考点介绍&#xff1a; 大厂面试时&#xff0c;面试官提出的问题除了了解经历和想法外&#xff0c;最看重的是思维逻辑能力、团队协作能力和协调能力。 『产品面试之面试官的真实意图』相关题目及解析内容可点击文章末尾链接查看&#xff01; 一、考点题目 1. 你遇到的最大的…

QT 相关设置

目录 1.安装QT2.安装好之后需要做一些设置2.1 基本的字体及主题设置2.2 格式化美化代码插件设置 1.安装QT 具体教程不写了 2.安装好之后需要做一些设置 2.1 基本的字体及主题设置 进入选项 选择喜欢的主题 字号字体设置 2.2 格式化美化代码插件设置 先下载一个格式化插…

五、多表查询-4.6练习

一、准备数据 【效果展示】 emp1表&#xff08;员工表&#xff09;&#xff1a; dept1表&#xff08;部门表&#xff09;&#xff1a; salgrade表&#xff08;薪资等级表&#xff09;&#xff1a; 二、案例 1、查询员工的姓名、年龄、职位、部门信息&#xff08;隐式内连接&am…

JUC详解

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱发博客的嗯哼&#xff0c;爱好Java的小菜鸟 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;社区论坛&#xff1a;希望大家能加入社区共同进步…

leetcode 823. 带因子的二叉树(dp+双指针+Long类型)

leetcode 823. 带因子的二叉树(dp双指针Long类型) 题目表述 给出一个含有不重复整数元素的数组 arr &#xff0c;每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树&#xff0c;每个整数可以使用任意次数。其中&#xff1a;每个非叶结点的值应等于它的两个子结点的值的乘积…

个人博客论坛系统测试报告

目录 一、项目介绍 二、测试计划 1、功能测试 &#xff08;1&#xff09;测试环境&#xff1a; &#xff08;2&#xff09;测试用例编写 &#xff08;3&#xff09;部分功能测试 2、自动化测试 &#x1f351;注册页面测试 验证注册成功的情况 验证注册失败的情况 &a…