泛型和通配符

news2024/11/22 5:40:39

目录

1. 什么是泛型

2. 泛型是如何编译的?

3. 泛型的上界

小栗子1:

小栗子2:

4. 泛型方法

5. 通配符

小栗子:

错误的做法和原因: 

6. 通配符的上界(多用来取数据)

7. 通配符的下界(多用来放数据)


1. 什么是泛型

泛型就是对类型进行参数化。

类名<T>  这就是一个泛型类,其中<T>是占位符,T是类型形参

泛型传的是类类型

泛型的作用:数据类型参数化,编译时自动进行类型检查和转换。

下面是定义的一个泛型类(MyArray<T>)以及这个泛型类的使用:

2. 泛型是如何编译的?

在编译时,所有T都会被擦除成Object,即擦除机制。当运行时,没有泛型的概念,全部是Object

下图中这些T都会被擦除成Object:

那泛型还有什么用?指定类型有啥用?

作用:根据传入的类型来自动进行类型的检查和转换。(即1. 存放元素的时候,会进行类型的检 2. 取出元素的时候,会自动发生类型转换)

比如传入Integer类型,(1)会检查传入的val是否为Integer类型,不是会编译报错(下图蓝色框框);(2)返回类型会自动转换成Integer类型(下图黄色框框部分)

流程:检查转换,编译,擦除,运行


我们看下面代码:(输出引用中存的地址)

 

我们发现,运行后,它们的类型中没有<>了。也就是说这些地方编译后直接被擦没了,<>不参与类型的组成。

编译后,左图所有T会被擦除成Object,右图红色框框部分会直接擦没。

3. 泛型的上界

类名<T extends 类型边界> 

有上界的泛型类,编译时,所有T都会被擦除成给的类型边界,不会擦除成Object。

没有上界,编译时,所有T都会被擦除成Object

如:

类名<T extends Number> —— 表示T一定是Number的子类或Number本身(Number是数值类)

类名<T extends Comparable<T>> —— 表示T一定实现了Comparable接口

小栗子1:

黄色框框的作用: 检查传入的类类型是否是Number的子类或Number本身,不是则编译报错。

小栗子2:

题目:有一个泛型类,类中有一个方法,方法作用是求数组中的最大值

分析: 

T是类型形参,接收的是类类型,即引用类型。引用类型定义的变量max不能通过>或<进行比较。需要通过实现Comparable接口,重写compareTo方法进行比较。(对应上图红色框框)

橘色框框的作用:检查传入的类类型是否实现了此接口,没有实现会编译报错。如下图:

正确做法如下: 传入的Person类型需要实现此接口

为啥Integer类型直接传入不报错?

因为Integer类自己实现了Comparable接口。

4. 泛型方法

非静态泛型方法:方法限定符 <T> 返回值类型 方法名(形参){...}

静态泛型方法:   方法限定符 static <T> 返回值类型 方法名(形参){...}

 ret 和 ret2 这两种都可以,一般省略不写(ret2形式),传的类型会联系上下代码自动推导出。

5. 通配符

?—— 通配符,用在泛型的使用中。

泛型的类型形参T接收的是类类型,比如包装类Integer,Double,或者自定义类型Person等。T是确定的类型,一旦你传了,我就定下来了。

而当我们传递的实参是泛型类型时,有没有一个东西可以接收类型形参不确定的泛型类型呢?

于是有了通配符。

小栗子:

有一个泛型类Message<T>,里面有set和get方法。在main函数中,我们调用set方法赋值。接着调用一个static方法func,传入message引用。在func方法中调用get方法。

分析:

由于func方法形参接收的是message引用,这个引用的类型是不确定的,可以是Message<Integer>,也可以是Message<String>,等。

总之,message的类型是一个参数不确定的泛型。(注意:1.接收的message的类型是泛型类型

2.这个泛型参数不确定)

所以func的形参是Message<?> message ,没错,接收参数不确定的泛型就用到了通配符(?)。

如下图:

但是static方法func中不能调用set方法,因为 通配符?接收的参数不确定,站在message角度,我已经来者不拒了,我怎么知道 ? 接收的是什么类型,而set方法需要传?类型的参数,所以传什么都不对。如下图:

通配符一般在使用的时候会给边界,否则它不能匹配到任何类型。给边界了,就可控了。  


错误的做法和原因: 

如果不使用通配符,就是上述做法。咦?不应该发生方法重载吗?怎么会报错?

我们来看一下报错信息:

两种方法具有相同的擦除效果。哦,原来是这样。

因为编译后,<>直接会被擦没,<>不参与类型的组成。所以不构成重载,而是变成了两个一模一样的方法。因此,就报错啦。

6. 通配符的上界(多用来取数据)

<? extends 上界> —— 表示通配符?可以接收的实参类型是“上界”的子类或者“上界”本身。

如:

<? extends Number> —— 表示通配符?可以接收的实参类型是Number的子类或者Number本身

我们一般使用通配符的上界来取数据不能放入数据。

如下:

可以取数据(绿色框框),不能放数据(红色框框)

可以取数据:可以用Fruit类型的引用接收 取的数据 原因:? 接收的要么是Fruit类,要么是它的子类。是子类就会发生向上转型。所以可以接收。

不能放数据:因为通配符?接收的类型不能确定,tmp可能是plate1(Apple),也可能是plate2(Banana),set方法的参数T类型不能确定,所以无法放数据。

7. 通配符的下界(多用来放数据)

<? super 上界> —— 表示通配符?可以接收的实参类型是“上界”的父类或者“上界”本身。

如:

<? super Fruit> —— 表示通配符?可以接收的实参类型是Fruit的父类或者Fruit本身

我们一般使用通配符的下界来放(下界的子类或本身)的数据不取数据。

如下:

 

  

放数据:可以放Fruit的子类或本身(绿色框框),不能放Fruit的父类(蓝色框框)

因为<? super Fruit>表示 ?只能是Fruit的父类或本身。虽然通配符?类型不确定,但可以确定要么是Fruit,要么是Fruit的父类。所以放Fruit子类类型的数据会自动发生向上转型。虽然因为 T 的类型不确定,所以向上转型成什么类型是不确定的,但能发生向上转型就够了。证明可以放Fruit的子类或本身。

而Fruit父类类型的数据照样不能放。因为类型不确定,根本不知道?接收的是哪个类型。所以放父类数据是不合适的。

不能取数据

因为?要么是Fruit的父类,要么是Fruit本身。所以get方法返回值 T 的类型不确定,也就是说,我们无法知道取出的数据类型是什么,那么,我们用什么接收都不妥。因为没有给上界呀。无法发生向上转型。

但说实话,取数据接收其实也是可以的,

第一种:我们可以用Object接收,因为Object类是所有类的父类,可以发生向上转型。

第二种:直接输出也是可以的。

如下图:

 

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

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

相关文章

【C#学习笔记】类型转换

文章目录 类型转换字符转数字GetNumericValueConvert.ToInt32隐式转换计算 字符串转数字Parse 或 TryParse 方法 字节数组转整数 as&#xff0c;is强制类型转换isas 用户定义的转换 类型转换 我们简单地将值类型分为5种&#xff1a;整数型&#xff0c;浮点型&#xff0c;布尔型…

Docker环境下MySQL备份恢复工具XtraBackup使用详解 | Spring Cloud 62

一、XtraBackup 简介 Percona XtraBackup是一个开源的MySQL和MariaDB数据库备份工具&#xff0c;它能够创建高性能、一致性的备份&#xff0c;并且对生产环境的影响很小。Percona XtraBackup通过在不停止MySQL服务器的情况下&#xff0c;复制InnoDB存储引擎的数据文件和事务日…

react18之08自定义hook (简单的axios-get、修改浏览器title、localStorage、获取滚动条位置、img转换为base64)

目录 react18之自定义hook ()01&#xff1a;自定义一个 简单的axios hook 发起get请求useHttp.jsx使用useHttp hook效果 02&#xff1a;自定义一个 修改浏览器title hook03&#xff1a;自定义一个 localStorage(获取、存储、移除) hookuseLocalStorage.jsx使用hook效果 04&…

【JVM】 垃圾回收篇——自问自答(1)

Q什么是垃圾&#xff1a; 运行程序中&#xff0c;没用任何指针指向的对象。 Q为什么需要垃圾回收&#xff1f; 内存只分配&#xff0c;不整理回收&#xff0c;迟早会被消耗完。 内存碎片的整理&#xff0c;为新对象腾出空间 没有GC程序无法正常进行。 Q 哪些区域有GC&#…

【C++学习】STL容器——list

目录 一、list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list 迭代器失效 二、list的模拟实现 2.1 模拟实现list 三、list和vector的对比…

On Evaluation of Embodied Navigation Agents 论文阅读

论文信息 题目&#xff1a;On Evaluation of Embodied Navigation Agents 作者&#xff1a;Peter Anderson&#xff0c;Angel Chang 来源&#xff1a;arXiv 时间&#xff1a;2018 Abstract 过去两年&#xff0c;导航方面的创造性工作激增。这种创造性的输出产生了大量有时不…

idea-Invalidate caches选项

Clear file system cache and Local History: 清除 IntelliJ IDEA 缓存和本地历史记录&#xff0c;注意要保存现有的信息 Clear VCS Log caches and indexes: remove the cache and indexes of the VCS Log. 这个选项的意思是清除版本控制系统日志的缓存和索引。VCS Log 是 In…

VBA技术资料MF40:VBA_计数筛选状态的数据行数

【分享成果&#xff0c;随喜正能量】人唯有与喜欢的事物发展关系&#xff0c;不管是人或者是物还是事&#xff0c;包括喜欢自己外表、个性的部分&#xff0c;喜欢自己做的事&#xff0c;喜欢自己的创造&#xff0c;喜欢的风景……才给人带来对自己的认同。在与喜欢的事物互动关…

从小白到数据库达人!Mysql优化让你的社招面试无往不利!

大家好&#xff0c;我是小米&#xff0c;在这个美好的时刻又迎来了我们的技术小窝。今天&#xff0c;我们要聊一聊一个在数据库领域中无比重要的话题 —— Mysql 优化&#xff01;是不是感觉很兴奋呢&#xff1f;废话不多说&#xff0c;让我们直接进入今天的主题。 背景知识 …

Hadoop理论及实践-HDFS的Namenode及Datanode(参考Hadoop官网)

HDFS有什么特点&#xff0c;被设计做什么 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。有一下几个特点&#xff1a; HDFS是一个高度容错性的系统&#xff0c;具有高容错、高可靠性、高扩展性的特点&#xff0c;适合部…

2.两数相加(题解)

两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都…

数学建模—多元线性回归分析(+lasso回归的操作)

第一部分&#xff1a;回归分析的介绍 定义&#xff1a;回归分析是数据分析中最基础也是最重要的分析工具&#xff0c;绝大多数的数据分析问题&#xff0c;都可以使用回归的思想来解决。回归分析的人数就是&#xff0c;通过研究自变量X和因变量Y的相关关系&#xff0c;尝试去解释…

MongoDB 使用总结

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

MyCat配置文件schema.xml讲解

1.MyCat配置 1.1 schema标签 如果checkSQLschema配置的为false&#xff0c;那么执行DB01.TB_ORDER时就会报错&#xff0c;必须用use切换逻辑库以后才能进行查询。 sqlMaxLimit如果未指定limit进行查询&#xff0c;列表查询模式默认为100,最多只查询100条。因为用mycat后默认数…

【多线程】synchronized 原理

1. 写在前面 本章节主要介绍 synchronized 的一些内部优化机制&#xff0c;这些机制存在的目的呢就是让 synchronized 这把锁更高效更好用&#xff01; 2. 锁升级/锁膨胀 JVM 将 synchronized 锁分为以下四种状态&#xff1a; 无锁&#xff0c;偏向锁&#xff0c;轻量级锁&…

ENSP软件的基本使用命令(第三十一课)

ENSP软件的基本使用命令(第三十一课) 下面的图片是今天操作的核心基础操作 1 命令行页面 交换机 路由器 PC机 分别展示一下 页面的样子 2 基本命令结构

K8S系列文章 之 容器存储基础 Volume

Volume Volume是容器数据卷。我们经常创建删除一些容器&#xff0c;但有时候需要保留容器中的一些数据&#xff0c;这时候就用到了Volume。它也是容器之间数据共享的技术&#xff0c;可以将容器中产生的数据同步到本地。实际就是把容器中的目录挂载到运行着容器的服务器或个人…

Last-Mile Embodied Visual Navigation 论文阅读

论文阅读 题目&#xff1a;Last-Mile Embodied Visual Navigation 作者&#xff1a;JustinWasserman, Karmesh Yadav 来源&#xff1a;CoRL 时间&#xff1a;2023 代码地址&#xff1a;https://jbwasse2.github.io/portfolio/SLING Abstract 现实的长期任务&#xff08;例如…

Spring Cloud Gateway过滤器GlobalFilter详解

一、过滤器的场景 在springCloud架构中&#xff0c;网关是必不可少的组件&#xff0c;它用于服务路由的转发。对客户端进行屏蔽微服务的具体细节&#xff0c;客户端只需要和网关进行交互。所以网关顾名思义&#xff0c;就是网络的一个关卡。它就是一座城的城门守卫。所以这个守…

10亿数据、查询<10s,论基于OLAP搭建广告系统的正确姿势

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 由于流量红利逐渐消退&#xff0c;越来越多的广告企业和从业者开始探索精细化营销的新路径&#xff0c;取代以往的全流量、粗放式的广告轰炸。精细化营销意味着要在…