【JavaSE】泛型中的通配符

news/2024/5/9 17:25:46/文章来源:https://blog.csdn.net/weixin_51146329/article/details/129699579

文章目录

  • 1. 概述
  • 2. 上界通配符 < ? extends E>
  • 3. 下界通配符 < ? super E>
  • 3. ?和 T 的区别

1. 概述

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许开发者在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

在定义泛型类、泛型方法、泛型接口的时候会经常碰到很多泛型通配符,比如 T,E,K,V 等等。

这些通配符实际上只是一个约定,用26个字母中的任意一个都行,并不会影响程序的正常运行,通常来说有以下约定:

  • ?表示不确定的 java 类型,用作 参数类型、字段类型、局部变量类型,有时作为返回类型(但请避免这样做)
  • T (type) 表示具体的一个java类型,用作 声明类的类型参数、通用方法的类型参数 (这里注意 类型参数 和 参数类型 是两个概念)
  • K V (key value) 分别代表java键值中的Key Value
  • E (element) 代表Element

使用 ? 的时候并并不知道也不关心这个时候的类型,这里只想使用其通用的方法,而且 ? 通配符是无法作用于声明类的类型参数,一般作用于方法和参数上。而类型变量 T 在类定义时具有更广泛的应用。


2. 上界通配符 < ? extends E>

上界:用 extends 关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类。

在类型参数中使用 extends 表示这个泛型中的参数必须是 E 或者 E 的子类,这样有两个好处:

  • 如果传入的类型不是 E 或者 E 的子类,编译不成功
  • 泛型中可以使用 E 的方法,要不然还得强转成 E 才能使用
public class Test {static int countLegs (List<? extends Animal > animals ) {int retVal = 0;for ( Animal animal : animals ){retVal += animal.getCount();}return retVal;}static int countLegs1 (List<Animal> animals ){int retVal = 0;for ( Animal animal : animals ){retVal += animal.getCount();}return retVal;}public static void main(String[] args) {List<Dog> dogs = new ArrayList<>();// 不会报错countLegs( dogs );// 报错countLegs1(dogs);}
}

通配符其实在声明局部变量时是没有什么意义的,但是当为一个方法声明一个参数时,它是非常重要的。

image-20230317150200751

对于不确定或者不关心实际要操作的类型,可以使用无限制通配符(尖括号里一个问号,即 <?> ),表示可以持有任何类型。像 countLegs 方法中,限定了上界,但是不关心具体类型是什么,所以对于传入的 Animal 的所有子类都可以支持,并且不会报错。而 countLegs1 就不行。


3. 下界通配符 < ? super E>

下界: 用 super 进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至 Object

在类型参数中使用 super 表示这个泛型中的参数必须是 E 或者 E 的父类

private <T> void test(List<? super T> dst, List<T> src) {for (T t : src) {dst.add(t);}
}public static void main(String[] args) {List<Dog> dogs = new ArrayList<>();List<Animal> animals = new ArrayList<>();new Test().test(animals, dogs);
} // Dog 是 Animal 的子类 class Dog extends Animal {
}

dst 类型 “大于等于” src 的类型,这里的“大于等于”是指 dst 表示的范围比 src 要大,因此装得下 dst 的容器也就能装 src 。


3. ?和 T 的区别

?和 T 都表示不确定的类型,区别在于可以对 T 进行操作,但是对 ?不行

// 可以 
T t = operate(); 
// 不可以 
? car = operate();

因此,T 是一个 确定的 类型,通常用于泛型类和泛型方法的定义,?是一个 不确定 的类型,通常用于泛型方法的调用代码和形参,不能用于定义类和泛型方法。

可以使用T来确保泛型参数的一致性

// 通过 T 来 确保 泛型参数的一致性
public <T extends Number> void
test(List<T> dest, List<T> src)//通配符是 不确定的,所以这个方法不能保证两个 List 具有相同的元素类型
public void
test(List<? extends Number> dest, List<? extends Number> src)

类型参数可以多重限定而通配符不行

public class Test {public <T extends Dog & Animal> void hello(T t){}
}

使用 & 符号设定多重边界,指定泛型类型 T 必须是 Dog 和 Animal 的共有子类型,此时变量 t 就具有了所有限定的方法和属性。对于通配符来说,因为它不是一个确定的类型,所以不能进行多重限定。

image-20230317152345434

通配符可以使用超类限定而类型参数不行

类型参数 T 只具有 一种 类型限定方式:

T extends A

但是通配符 ? 可以进行 两种限定:

? extends A ? super A


参考:Java 泛型 T,E,K,V,?,傻傻分不清?

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【QT神奇Bug】中文乱码、括号乱码、冒号乱码【2023.03.22】

&#x1f60d;Qt乱码疑难杂症解决方案 Solved by Yang Naifen. &#x1f4fa;视频讲解地址&#xff1a;【Qt疑难杂症之乱码-哔哩哔哩】 https://b23.tv/83MmXru 附言&#xff1a;解决这个bug按照我当前的薪资&#xff0c;至少四百RMB。都是工农阶级的工友&#xff0c;有bug一…

本地调试Java程序时只对部分接口忽略代理

场景 今天有位朋友问了个问题&#xff0c;在本地IDE开发工具调试代码的时候&#xff0c;怎么不动代码的情况只针对部分API走proxy&#xff0c;因为他们的代码只需要在本地调试的时候才要用到Proxy&#xff0c;而平时都是部署在云上&#xff0c;是用不到Proxy的&#xff0c;所以…

JDBC基础,介绍了简单的连接数据库,并通过在后端写SQL语句对数据库进行基本的增删查改操作

一、JDBC基础 跟数据库连接&#xff0c;并且可以对数据库里面的数据通过SQL语句进行处理等操作。 1.1 JDBC JDBC是SUN公司的&#xff0c;所以要按照他们的规范来&#xff0c;因为MYSQL和Oracle都是SUN公司的。三个产品都是一个公司的&#xff0c;一般不会出现兼容性不好的问…

智能手机2023:高端前攻、中端后守

配图来自Canva可画 沉寂许久的行业&#xff0c;终于在疫情之后迎来了久违的舞台&#xff0c;MWC线下展会三年来第一次召开。2月27日至3月2日&#xff0c;2023年世界移动通讯大会如期在巴塞罗那举行&#xff0c;国内一众手机厂商们纷纷登台亮相、大秀肌肉。与以往相比&#xff…

Rocketmq-Mqtt 开发实例

一、RocketMQ MQTT 概览传统的消息队列MQ主要应用于服务&#xff08;端&#xff09;之间的消息通信&#xff0c;比如电商领域的交易消息、支付消息、物流消息等等。然而在消息这个大类下&#xff0c;还有一个非常重要且常见的消息领域&#xff0c;即IoT类终端设备消息。近些年&…

Tomcat源码:启动类Bootstrap与Catalina的加载

参考资料&#xff1a; 《Tomcat源码解析系列&#xff08;一&#xff09;Bootstrap》 《Tomcat源码解析系列&#xff08;二&#xff09;Catalina》 《Tomcat - 启动过程&#xff1a;初始化和启动流程》 《Tomcat - 启动过程:类加载机制详解》 《Tomcat - 启动过程:Catalina…

不用科学上网,免费的GPT-4 IDE工具Cursor保姆级使用教程

大家好&#xff0c;我是可乐。 过去的一周&#xff0c;真是疯狂的一周。 GPT-4 震撼发布&#xff0c;拥有了多模态能力&#xff0c;不仅能和GPT3一样进行文字对话&#xff0c;还能读懂图片&#xff1b; 然后斯坦福大学发布 Alpaca 7 B&#xff0c;性能匹敌 GPT-3.5&#xff…

易基因:PIWI/piRNA在人癌症中的表观遗传调控机制(DNA甲基化+m6A+组蛋白修饰)|综述

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。2023年03月07日&#xff0c;南华大学衡阳医学院李二毛团队在《Molecular Cancer》杂志发表了题为“The epigenetic regulatory mechanism of PIWI/piRNAs in human cancers”的综述文章&am…

数据处理时代,绕不开的数据分析

数据分析的出现是因为人类难以理解海量数据所呈现出来的信息&#xff0c;不能从中找到相应的规律来对现实中的事物进行对应&#xff0c;我们都知道数据有很高的价值&#xff0c;但不能利用的价值&#xff0c;没有任何意义。 为了解决这一问题&#xff0c;数据分析在长期的数据…

Golang每日一练(leetDay0012)

目录 34. 查找元素首末位置 Find-first-and-last-position-of-element-in-sorted-array &#x1f31f;&#x1f31f; 35. 搜索插入位置 Search Insert Position &#x1f31f; 36. 有效的数独 Valid Sudoku &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 …

[vue问题]Uncaught SyntaxError: Not available in legacy mode

[vue问题]Uncaught SyntaxError: Not available in legacy mode问题描述问题分析解决方案直接回退vue-i18n的版本解决错误提示的问题问题描述 Uncaught SyntaxError: Not available in legacy modeat Object.createCompileError (message-compiler.cjs.js?af13:58:1)at creat…

GTC 2023 | 「皮衣刀客」黄仁勋畅谈 AI Top 5,科学计算、生成式 AI、Omniverse 榜上有名

内容一览&#xff1a;北京时间 3 月 21 日 23:00&#xff0c;英伟达创始人兼 CEO 黄仁勋在 GTC 2023 上发表主题演讲&#xff0c;介绍了生成式 AI、元宇宙、大语言模型、云计算等领域最新进展。 关键词&#xff1a;英伟达 黄仁勋 GTC 2023 「Don’t Miss This Defining Momen…

辉煌优配|沪指震荡涨0.25%,建筑、家居等板块拉升,数字经济概念活跃

22日早盘&#xff0c;两市股指盘中强势上扬&#xff0c;接近午盘涨幅收窄&#xff1b;两市半日成交近6000亿元&#xff0c;北向资金小幅净流出。 到午间收盘&#xff0c;沪指涨0.25%报3263.85点&#xff0c;深成指涨0.39%&#xff0c;创业板指微跌0.01%&#xff0c;两市合计成交…

html(1)

创建html项目 新建html项目&#xff0c;用记事本打开&#xff1a; 只需要浏览器就可以执行里面的代码&#xff0c;不需要安装额外的运行环境&#xff08;例如JDK&#xff09; html不需要编译&#xff0c;浏览器读取后就可以执行 上述hello world在文件是如下代码&#xff1a…

静态版通讯录的实现(详解)

前言&#xff1a;内容包括三个模块&#xff1a;测试通讯录模块&#xff0c;声明模块&#xff0c;通讯录实现模块 实现一个通讯录&#xff1a; 1 可以存放100个人的信息 每个人的信息&#xff1a; 名字 性别 年龄 电话 地址 2 增加联系人信息 删除联系人信息 查找联系人信息…

windows无盘启动技术开发之传统BIOS(Legacy BIOS)引导程序开发之二

by fanxiushu 2023-03-21 转载或引用请注明原始作者&#xff0c;接上文&#xff0c;这篇文章其实主要就是讲述上文中 Int13HookEntry 这个C函数的实现过程&#xff0c;看起来就一个函数&#xff0c;可实现起来一点也不轻松。首先得准备编译环境&#xff0c;因为是16位程序&…

LeetCode岛屿问题通用解决模板

文章目录前言第一题&#xff1a;求岛屿的周长模板整理遍历方向确定边界重复遍历问题处理模板解第一题第二题&#xff1a;求岛屿数量第三题&#xff1a;岛屿的最大面积第四题&#xff1a;统计子岛屿第五题&#xff1a;统计封闭岛屿的数目第六题&#xff1a;最大人工岛总结前言 …

04.hadoopHDFS

win java访问hadoop //复制文件夹,配置环境变量//配置HADOOP_HOME为我们的路径 ,hadoop-3.3.0 ,记得JAVA_HOME不要带有空格,!!!默认java安装环境有空格C:\Program Files//要在cmd hadoop -fs 查看是否配置成功//%HADOOP_HOME%\bin到path//maven添加依赖hadoop3.1.0//创建目录Be…

常见的CMS后台getshell姿势总结

目录 WordPress dedecms aspcms 南方数据企业系统 phpmyadmin日志 pageadmin 无忧企业系统 WordPress 默认后台登录地址 /wp-login.php /wp-admin 登录后在外观的编辑里面找一个模板&#xff0c;我们在404模板 (404.php)里面写入一句话后门 可以蚁剑连接 上传一个压缩…

自定义类型的超详细讲解ᵎᵎ了解结构体和位段这一篇文章就够了ᵎ

目录 1.结构体的声明 1.1基础知识 1.2结构体的声明 1.3结构体的特殊声明 1.4结构体的自引用 1.5结构体变量的定义和初始化 1.6结构体内存对齐 那对齐这么浪费空间&#xff0c;为什么要对齐 1.7修改默认对齐数 1.8结构体传参 2.位段 2.1什么是位段 2.2位段的内存分配…