【Java 基础篇】Java类型通配符:解密泛型的神秘面纱
在Java中,类型通配符(Type Wildcard)是泛型的重要概念之一。它使得我们能够更加灵活地处理泛型类型,使代码更通用且可复用。本文将深入探讨Java类型通配符的用法、语法和最佳实践。
什么是类型通配符?
类型通配符是一个用问号 ?
表示的通配符,它可以用于泛型类、方法和通配符边界。类型通配符的主要作用是让我们能够接受各种类型的数据,而不需要知道具体的类型参数。
基本语法
类型通配符的基本语法如下:
List<?> list = new ArrayList<>();
在这个例子中,List<?>
表示一个可以接受任何类型的列表。我们可以将任何类型的列表赋值给这个变量,例如 List<String>
、List<Integer>
、List<Double>
等。
通配符的用途
类型通配符主要用于以下几种情况:
1. 方法参数接受各种类型
通配符可用于方法参数,使得方法可以接受各种类型的数据,而不需要为每种类型都写一个重载方法。例如:
public void printList(List<?> list) {for (Object item : list) {System.out.print(item + " ");}System.out.println();
}
上述方法 printList
可以接受任何类型的列表,并打印列表中的元素。
2. 泛型类中的通用字段
通配符还可用于泛型类中的字段,以允许字段接受不同类型的数据。例如,考虑以下泛型类:
public class Box<T> {private T value;public Box(T value) {this.value = value;}public T getValue() {return value;}
}
如果我们希望创建一个通用的 Box
类,可以接受任何类型的值,可以使用类型通配符:
public class Box<?> {private Object value;public Box(Object value) {this.value = value;}public Object getValue() {return value;}
}
这样,Box
类就可以接受任何类型的值。
3. 通配符边界
类型通配符还可以与通配符边界一起使用,以限制通配符可以接受的类型。通配符边界使用 extends
和 super
关键字来定义上限和下限。
? extends T
:表示通配符可以接受T
类型或其子类型。? super T
:表示通配符可以接受T
类型或其父类型。
下面是一个示例,演示如何使用通配符边界:
public void process(List<? extends Number> list) {// 在这里可以安全地读取 Number 或其子类型的数据for (Number number : list) {System.out.print(number + " ");}System.out.println();
}
在这个示例中,process
方法接受一个限定为 Number
或其子类型的列表,可以安全地读取其中的数据。
通配符的注意事项和最佳实践
使用类型通配符时,需要注意以下几点:
1. 通配符捕获
当使用通配符作为方法参数时,通配符的类型信息在方法内部是不可用的。例如,以下代码是无效的:
public void process(List<?> list) {// 无法在这里添加元素到通配符列表list.add("Hello");
}
这是因为编译器无法确定通配符的具体类型。要解决这个问题,可以使用通配符捕获和辅助方法来处理通配符列表,如下所示:
public void process(List<?> list) {processList(list);
}private <T> void processList(List<T> list) {// 在这里可以添加元素到列表list.add("Hello");
}
2. 类型通配符与原始类型的区别
类型通配符 List<?>
和原始类型 List
是不同的。前者表示可以接受任何类型的列表,而后者表示一个未知类型的列表。通常情况下,应该使用类型通配符来保持类型安全。
3. 通配符上限和下限的选择
在使用通配符边界时,需要根据具体的需求选择合适的上限或下限。如果需要接受子类型,使用 ? extends T
;如果需要接受父类型,使用 ? super T
。选择正确的边界可以提高代码的灵活性和安全性。
类型通配符使用注意事项
当使用类型通配符时,有一些注意事项需要牢记,以确保代码的正确性和可维护性。以下是一些关于类型通配符的使用注意事项:
1. 无法添加具体类型的元素
使用通配符 List<?>
时,不能向列表中添加具体类型的元素。这是因为通配符表示一个未知类型,编译器无法确定允许添加哪种类型的元素。例如,下面的代码是非法的:
List<?> list = new ArrayList<>();
list.add("Hello"); // 非法操作
要解决这个问题,可以使用通配符捕获和辅助方法来添加元素,如上文所示。
2. 通配符捕获
当使用通配符作为方法参数时,通配符的类型信息在方法内部是不可用的。这意味着您不能在方法内部访问通配符的具体类型。为了处理通配符列表中的元素,您需要使用通配符捕获和辅助方法。
3. 通配符与原始类型的区别
通配符 List<?>
和原始类型 List
是不同的。前者表示可以接受任何类型的列表,而后者表示一个未知类型的列表。通常情况下,应该使用类型通配符来保持类型安全。
4. 通配符边界的选择
在使用通配符边界时,需要根据具体的需求选择合适的上限或下限。如果需要接受子类型,使用 ? extends T
;如果需要接受父类型,使用 ? super T
。选择正确的边界可以提高代码的灵活性和安全性。
5. 通配符的通用性
通配符使代码更通用,但有时也可能导致类型不安全的情况。因此,在使用通配符时要谨慎,确保不会破坏类型安全性。
总之,类型通配符是Java泛型编程的强大工具,可以使代码更灵活和通用。然而,在使用时需要谨慎处理,特别是在添加元素和处理通配符类型时。通过遵循上述注意事项,您可以更好地利用类型通配符来编写高质量的Java代码。
结语
Java类型通配符是泛型编程的重要组成部分,它使得代码更加灵活和通用。通过了解类型通配符的基本语法和最佳实践,您可以更好地应用它们来编写类型安全且
可复用的代码。希望本文能够帮助您更好地理解和使用Java类型通配符。
如果你想深入了解更多关于Java泛型和类型通配符的知识,可以查阅官方文档或相关教程。愿您的Java编程之路越来越顺利!
相关文章:

【Java 基础篇】Java类型通配符:解密泛型的神秘面纱
在Java中,类型通配符(Type Wildcard)是泛型的重要概念之一。它使得我们能够更加灵活地处理泛型类型,使代码更通用且可复用。本文将深入探讨Java类型通配符的用法、语法和最佳实践。 什么是类型通配符? 类型通配符是一…...
《极客时间:如何成为学习高手》【方法论】
本篇博客是学习过程中的笔记整理和个人思考。原文链接:https://time.geekbang.org/column/intro/100081501?tabcatalog 底层逻辑01|如何减少对学习的排斥和厌恶心理,使其变得相对愉悦?02|学会这 4 点,你也…...
如何处理ChatGPT在文本生成中的语法错误和不合理性?
ChatGPT是一种强大的自然语言处理模型,但它并不是完美的,有时会产生语法错误或不合理的文本。这些问题可能会影响模型生成的内容的质量和可信度。在处理ChatGPT中的语法错误和不合理性时,有许多方法和策略可以采用,以下是一些详细…...
GitHub常用命令
1. 将本文件夹初始化为一个本地git仓库 git init 2. 将github的远程克隆到本地 git clone XXX 3. 添加所有文件到暂存区 git add . 4. 删除工作区文件 git rm [file] 5. 提交 git commit -m "提交信息(比如:my first commit fileÿ…...

【Linux学习笔记】 - 常用指令学习及其验证(上)
前言:本文主要记录对Linux常用指令的使用验证。环境为阿里云服务器CentOS 7.9。关于环境如何搭建等问题,大家可到同平台等各大资源网进行搜索学习,本文不再赘述。 由于本人对Linux学习程度尚且较浅,本文仅介绍验证常用指令的常用…...

火山引擎边缘云助力智能科技赋予生活更多新意
当下,先进的科学技术使得我们的日常生活变得快捷、舒适。大到上百层智能大厦、高端公共场所、社会智能基础设施,小到智能家居监控、指纹密码锁等,在这个充满想象力的时代,科技以更加智能化的方式改变和守护我们的生活。 引入智能…...
【无标题】CTreeCtrl更改-/+展开按钮颜色
#pragma once #include <list>// CMyTreeCtrlclass CMyTreeCtrl : public CTreeCtrl {private:std::list<std::...

【深度学习】 Python 和 NumPy 系列教程(十九):Matplotlib详解:2、3d绘图类型(5)3D等高线图(3D Contour Plot)
目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 0. 设置中文字体 1. 3D线框图(3D Line Plot) 2. 3D散点图(3D Scatter Plot) 3. 3D条形图(3D Bar Plot) 4. 3D曲面图…...
Java ZGC 算法调优
ZGC 是一种专门的垃圾收集器,专注于管理大型堆并最大限度地减少 Java 应用程序中的暂停。它解决了内存密集型工作负载和一致的响应时间至关重要的场景中垃圾收集的挑战。利用并发处理能力和先进算法,ZGC 为优化 Java 应用程序的性能提供了有效的解决方案…...

【海思SS626 | 开发环境】编译整个SDK全过程以及问题汇总
目录 一、概述二、解压SDK,打补丁三、安装交叉编译工具✨3.1 安装 aarch64-mix410-linux.tgz✨3.2 安装 cc-riscv32-cfg11-musl-20220523-elf.tar.gz✨3.3 检查工具链版本,打印版本则表示安装成功 四、安装软件包✨4.1 安装软件包✨4.2 安装mtd-utils的依…...

83 # 静态服务中间件 koa-static 的使用以及实现
静态服务中间件:koa-static 中间件可以决定是否向下执行,如果自己可以处理,那么直接处理完毕结束,如果自己处理不了,next 方法会继续向下执行 新建 public 文件夹,里面添加 index.html、style.css 文件 …...

带讲解的自行车租赁系统,可做毕设/课设
适合人群: 马上毕业/需要毕设的同学 技术栈: 前后端分离 前端使用: Vue Element 后端使用: SpringBoot Mysql8.0 Mybatis 支付宝支付 功能截图: 分为管理员端和 普通用户端 和 维修人员端 阿里大佬亲讲 免费看地址: 见评论区...
mysql指令
1.删除表: drop table table_name; 2.查询表字段: select COLUMN_NAME from information_schema.COLUMNS where TABLE_NAMEtable_name; 参考链接 3.切换数据库: use database_name 4.查看当前数据库所有表 show tables;...

【C语言】每日一题(半月斩)——day2
目录 一.选择题 1、以下程序段的输出结果是( ) 2、若有以下程序,则运行后的输出结果是( ) 3、如下函数的 f(1) 的值为( ) 4、下面3段程序代码的效果一样吗( ) 5、对于下面的说法,正确的是…...
电脑如何查看代理服务器IP?
许多人在使用互联网时可能会遇到需要使用代理服务器的情况。但是,你知道如何在电脑上查看代理服务器IP吗?本文将为您分享简单易懂的方法,帮助您轻松了解代理设置的秘密! 代理服务器在网络世界中担任着重要的角色,它可…...

【C++11】{}初始化、std::initializer_list、decltype、STL新增容器
文章目录 1. C11简介2. 统一的列表初始化2.1 {}初始化2.2 std::initializer_list 3. 声明3.1 auto3.2 decltype 4. nullptr5. 范围for循环6. 智能指针7. C11STL中的一些变化8. 演示代码 1. C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1…...

【FPGA项目】进阶版沙盘演练——报文收发(报文处理、CDC、CRC)
前言 书接上文【FPGA项目】沙盘演练——基础版报文收发_子墨祭的博客-CSDN博客,前面我们做了基础版的报文收发,相信对逻辑设计有了一定的认知,在此基础上,继续完善一个实际报文收发可能会遇到的一些处理: 报文处理握手…...
【程序员装机】自定义Edge浏览器用户目录
文章目录 前言修改Edge用户目录的批处理脚本上述批处理脚本的功能包括 总结 前言 本文将介绍Edge浏览器用户目录的批处理脚本方式修改,以自定义Edge浏览器的磁盘缓存目录和用户数据目录。 修改Edge用户目录的批处理脚本 以下是一个用于修改Edge浏览器用户目录的批…...

ubuntu18、20 cv_bridge 与自带opencv版本冲突问题
背景: nvidia tx2、xvaier 装机自带 ubuntu18 opencv4 后来我们会安装melodic的ros,ros中的cv_bridge 默认cv版本是3.2.0 编译带cv_bridge的代码时,会报错会崩溃,因为版本冲突了 为了解决该问题, 行之有效的一种…...

贝叶斯分位数回归、lasso和自适应lasso贝叶斯分位数回归分析免疫球蛋白、前列腺癌数据...
原文链接:http://tecdat.cn/?p22702 贝叶斯回归分位数在最近的文献中受到广泛关注,本文实现了贝叶斯系数估计和回归分位数(RQ)中的变量选择,带有lasso和自适应lasso惩罚的贝叶斯(点击文末“阅读原文”获取…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
Python的__call__ 方法
在 Python 中,__call__ 是一个特殊的魔术方法(magic method),它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时(例如 obj()),Python 会自动调用该对象的 __call__ 方法…...

HTML版英语学习系统
HTML版英语学习系统 这是一个完全免费、无需安装、功能完整的英语学习工具,使用HTML CSS JavaScript实现。 功能 文本朗读练习 - 输入英文文章,系统朗读帮助练习听力和发音,适合跟读练习,模仿学习;实时词典查询 - 双…...

DL00871-基于深度学习YOLOv11的盲人障碍物目标检测含完整数据集
基于深度学习YOLOv11的盲人障碍物目标检测:开启盲人出行新纪元 在全球范围内,盲人及视觉障碍者的出行问题一直是社会关注的重点。尽管技术不断进步,许多城市的无障碍设施依然未能满足盲人出行的实际需求。尤其是在复杂的城市环境中ÿ…...