最新要闻
- 十五五规划时期,未来十大新兴产业有哪些
- 世界视点!中兴Axon Pad来了:全球唯一5G双系统平板
- 医生误判将女孩恒牙当乳牙拔掉 科普:恒牙和乳牙区别
- 当前关注:日系车在中国真不香了!丰田、本田、日产、马自达全线暴跌
- 快资讯:iOS 16.4体验大翻车!苹果关闭降级通道:只许升新版
- 天天即时看!80/90后回忆杀!经典日漫《铁甲小宝》高清修复了:画质提升明显
- 世界观点:4月10日11时浙江嘉兴疫情最新消息 4月10日11时浙江嘉兴今日确诊人数
- 每日快播:米家空调巨省电首销:2匹大风量 2799元
- 环球热点!小米MIJIA智能音频眼镜发布!独特耳机眼镜二合一设计
- 世界热推荐:新手爸爸拿狗狗练拍嗝 网友:狗狗从来没享受过这么高的待遇
- 环球观察:周杰伦就不正当竞争起诉网易!4月17日开庭
- 日本非现金支付比例仅占36% 远落后于中国农村
- 重磅来了!
- 一季报预览:哪些公司业绩有望超预期
- 全球快看点丨迪拜拍出世界最贵车牌号:价值超1亿元!
- 各地开通旅游专列:去淄博吃烧烤都有专列了
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
当前短讯!Java-泛型机制详解
Java-泛型机制详解
1: 提出背景
Java集合(Collection)中元素的类型是多种多样的。例如,有些集合中的元素是Byte类型的,而有些则可能是String类型的,等等。Java允许程序员构建一个元素类型为Object的Collection,其中的元素可以是任何类型在[Java SE](https://baike.baidu.com/item/Java SE/4662159?fromModule=lemma_inlink) 1.5之前,没有泛型(Generics)的情况下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要作显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以在预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。因此,为了解决这一问题,J2SE 1.5引入泛型也是自然而然的了。
2: 泛型简介
泛型概念
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制
,该机制允许程序员在编译时
检测到非法的类型
。泛型的本质是参数化类型
,也就是说所操作的数据类型被指定为一个参数。
泛型作用
第一是泛化
【资料图】
可以用T代表任意类型Java语言中引入泛型是一个较大的功能增强不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了,这带来了很多好处。
第二是类型安全
泛型的一个主要目标就是提高Java程序的类型安全,使用泛型可以使编译器知道变量的类型限制,进而可以在更高程度上验证类型假设。如果不用泛型,则必须使用强制类型转换,而强制类型转换不安全,在运行期可能发生ClassCast Exception异常,如果使用泛型,则会在编译期就能发现该错误。
第三是消除强制类型转换
泛型可以消除源代码中的许多强制类型转换,这样可以使代码更加可读,并减少出错的机会。
第四是向后兼容
支持泛型的Java编译器(例如JDK1.5中的Javac)可以用来编译经过泛型扩充的Java程序(Generics Java程序),但是现有的没有使用泛型扩充的Java程序仍然可以用这些编译器来编译
3:泛型的基本使用
泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法。下面一部分例子参考与菜鸟教程网站(https://www.runoob.com/java/java-generics.html)
泛型类
泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。
例子:
- 简单泛型类
/** * * @param 此处是标识符号,T是type简称 */public class MyBox { /** * t的类型有T指定,创建该对象的时候,指定的类型 */ private T t; public void add(T t) { this.t = t; } public T get() { return t; }}public class MainTest { public static void main(String[] args) { MyBox stringMyBox = new MyBox<>(); stringMyBox.add("dddd"); System.out.println(stringMyBox.get()); MyBox integerMyBox = new MyBox<>(); integerMyBox.add(23); System.out.println(integerMyBox.get()); }}
- 多元泛型类
/** * * @param 变量key的类型,由外部指定 * @param 变量value的类型,由外部指定 */public class MyMap { private K key; private V value; public K getKey() { return this.key; } public V getValue() { return this.value; } public void setKey(K key) { this.key = key; } public void setValue(V value ){ this.value = value; }}public class MainTest { public static void main(String[] args) { MyMap stringStringMyMap = new MyMap<>(); stringStringMyMap.setKey("key1"); stringStringMyMap.setValue("key2"); System.out.println(stringStringMyMap.getKey()+"="+ stringStringMyMap.getValue()); MyMap stringIntegerMyMap = new MyMap<>(); stringIntegerMyMap.setKey("key1"); stringIntegerMyMap.setValue(1234); System.out.println(stringIntegerMyMap.getKey()+"="+ stringIntegerMyMap.getValue()); }}
泛型接口
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中
例子:
当实现泛型接口的类,没有传入泛型实参的时候:
/** * 定义一个泛型接口 * @param */public interface Generator { public T getNext(); }/** * 没有传入参数实参时,与泛型类的定义相同,在声明类的时候,需要将泛型的声明也一起加到类中 * @param */class GoodsGenerator implements Generator { @Override public T getNext() { return null; }}
当实现泛型接口的类,传入泛型实参时候:
/** * 传入泛型实参后,那么这个实现类里面的所有的参数都指定的类型,不能更改 * @param */public class MyGoodsGenerator implements Generator { private Params params = null; @Override public Params getNext() { return params; }}class Params { private String name; private String type; Params() {} Params(String name,String type) { this.name = name; this.type = type; }}
泛型方法
相对于泛型类,泛型方法就比较复杂了。
泛型类 是在实例化类的时候指明泛型的具体类型。而泛型方法
,是在调用
的时候指明泛型的具体类型
泛型方法规则
- 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的 )
- 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符
- 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符
- 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char等)
Java中泛型标记符
- E- Element (在集合中使用,因为集合中存放的是元素)
- T- Type(Java 类)
- K- Key(键)
- V- Value(值)
- N- Number(数值类型)
- ?- 表示不确定的 java 类型
下面我们看一个例子:
/** * 泛型方法 * 首先在public与返回值之间的必不可少,这表明这是一个泛型方法,并且声明了一个泛型T。 * 这个T可以出现在这个泛型方法的任意位置 * @param container 用来创建泛型对象 * @param 指明泛型T的具体类型 * @return * @throws IllegalAccessException * @throws InstantiationExceptio */ public T showKeyName(Class c) throws IllegalAccessException, InstantiationException { //创建对象 T t = c.newInstance(); return t; }
1: 为什么要用变量c来创建对象呢?
既然是泛型方法,就代表着我们不知道具体的类型是什么,也不知道构造方法如何,因此没有办法去new一个对象,但可以利用变量c的newInstance方法去创建对象,也就是利用反射创建对象。
泛型方法要求的参数是Class
类型,而Class.forName()
方法的返回值也是Class
,因此可以用Class.forName()
作为参数。当然,泛型方法不是仅仅可以有一个参数Class
,可以根据需要添加其他参数。
好处
因为泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候指明类型,更加灵活。
泛型的上下限
先看下下面的例子
public class Entity { } class BaseEntity extends Entity { }
//这两个方法编译不报错 public static void funA(Entity a) { // ... } public static void funB(BaseEntity b) { funA(b); // ... } //下面的funC(ListB)就会编译报错 public static void funC(List Entitys) { // ... } public static void funD(List BaseEntitys) { funC(BaseEntitys); // ... }
如何解决这个问题: 看下面的方法
public static void funC(List extends Entity> Entitys) { // ... } public static void funD(List BaseEntitys) { funC(BaseEntitys); // ... }
为了解决泛型中隐含的转换问题,Java泛型加入了类型参数的上下边界机制。 extends Entity>
表示该类型参数可以是Entity(上边界)或者Entity的子类类型。编译时擦除到类型Entity,即用Entity类型代替类型参数。这种方法可以解决开始遇到的问题,编译器知道类型参数的范围,如果传入的实例类型BaseEntity是在这个范围内的话允许转换,这时只要一次类型转换就可以了,运行时会把对象当做Entity的实例看待。
上限
public class MyEntity
{ private T value ; public void setVar(T var){ this.value = var ; } public T getVar(){ return this.value ; }}public class MainTest { public static void main(String[] args) { MyEntity longMyEntity = new MyEntity<>(); longMyEntity.setValue(10000000000000l); MyEntity integerMyEntity = new MyEntity<>(); integerMyEntity.setValue(1111); }} 下限
//前面举例的方法public static void funC(List extends Entity> Entitys) { // ...}
总结:
在使用泛型时,可以对传入的泛型类型实参进行上下边界的限制,如:类型实参只准传入某种类型的父类或某种类型的子类。
> 无限制通配符 extends E> extends 关键字声明了类型的上界, 表示参数化的类型可能是所指定的类型,或者是此类型的子类 super E> super 关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类
4: 泛型的好处
Java语言中引入泛型是一个较大的功能增强。不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了很大的改动,许多重要的类,比如集合框架,都已经成为泛型化的了。这带来了很多好处:
类型安全
泛型的主要目标是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在非常高的层次上验证类型假设
消除强制类型转换
泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会
更高的运行效率
在非泛型编程中,将筒单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销的。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作非常频繁的系统中,这个特点带来的性能提升更加明显
潜在的性能收益
泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,Java系统开发人员会指定这些强制类型转换)插入生成的字节码中。
关键词:
重点聚焦!SonarQube(CE)版集群环境下的高可用性实践
当前短讯!Java-泛型机制详解
最新快讯!Go常用库之GoRequests
十五五规划时期,未来十大新兴产业有哪些
世界视点!中兴Axon Pad来了:全球唯一5G双系统平板
医生误判将女孩恒牙当乳牙拔掉 科普:恒牙和乳牙区别
当前关注:日系车在中国真不香了!丰田、本田、日产、马自达全线暴跌
快资讯:iOS 16.4体验大翻车!苹果关闭降级通道:只许升新版
天天即时看!80/90后回忆杀!经典日漫《铁甲小宝》高清修复了:画质提升明显
【环球新要闻】全文索引:Apache Lucene(二)
Selenium做Web自动化踩过的坑
每日聚焦:通俗解释 JVM CAS 机制
世界观点:4月10日11时浙江嘉兴疫情最新消息 4月10日11时浙江嘉兴今日确诊人数
每日快播:米家空调巨省电首销:2匹大风量 2799元
环球热点!小米MIJIA智能音频眼镜发布!独特耳机眼镜二合一设计
世界热推荐:新手爸爸拿狗狗练拍嗝 网友:狗狗从来没享受过这么高的待遇
环球观察:周杰伦就不正当竞争起诉网易!4月17日开庭
日本非现金支付比例仅占36% 远落后于中国农村
重磅来了!
介绍一下sourcemap
今日关注:全网最详细中英文ChatGPT-GPT-4示例文档-文章大纲智能生成器从0到1快速入门——官网推荐的48种最佳应用场景(附python/node.js
一季报预览:哪些公司业绩有望超预期
全球快看点丨迪拜拍出世界最贵车牌号:价值超1亿元!
各地开通旅游专列:去淄博吃烧烤都有专列了
环球今亮点!米粉催卢伟冰发小米13 Ultra:我想冲顶配版
丰田在日召回超20万辆汽车:发动机有火灾隐患 已烧了两辆
世界观焦点:整合Microsoft 365服务:Win11文件管理器将迎来大更新
如何部署VSCODE SERVER
Silverlight教程_编程入门自学教程_菜鸟教程-免费教程分享
环球今日讯!围挡后面丨长沙河西首个三甲妇幼医院住院楼封顶!预计2025年建成投用
【天天新要闻】还去吗?泰国清迈发布“居家办公令” PM2.5超标准5倍:游客因空气污染锐减
“数学之王”丘成桐AI人工智能投入不能急功近利:中国很多技术卡脖子 基础科学没做好
元宇宙崩盘 林俊杰疑回应炒虚拟地产亏91%:听说很多人想帮我理财
北方大范围沙尘又来了 今年的沙尘天气为啥显得格外多?
天天观速讯丨通过 lua 进行 nginx redis 访问控制
焦点热议:多项数据向好 交通物流加速“跑起来”
环球要闻:背景太假哥疆域阿力木捡的狗“狼里狼气” 网友出谋划策辨认
【环球新视野】极氪X官宣4月12日上市:全能SUV 零百加速3秒级
焦点热文:我国构建世界首个番茄超泛基因组:能让番茄更好吃、产量多6成
全球播报:男女配合当街开井盖用勺挖地沟油被网友拍下引围观:行为太恶劣 应严惩
天天微资讯!林俊杰“炒房”浮亏91%?元宇宙泡沫的冰山一角
【时快讯】学系统集成项目管理工程师(中项)系列05_配置管理
天天动态:一不注意就被坑,家电“潜规则”早知道早好
今日热文:Spring5课堂笔记
Java8 Stream流式编程
【新要闻】128核心Arm处理器能跑Windows!还能配NVIDIA显卡
时讯:新疆和硕:田间地头 话两会
maptalks点线面图形样式设置经验总结
【天天速看料】马龙惊魂3-2拒绝一轮游,与小林再迎老少对决!国乒首日狂走钢丝
在米其林餐厅找罪受?人均8千元餐厅疑发生食物中毒
世界热点!张艺谋宣布将拍网剧《英雄联盟》!第一次 想拍个不一样的
环球新动态:Vulnhub Mercy靶场 Walkthrough
FSR、DLSS谁更好?26款游戏PK:AMD居然0胜!
环球速看:AI 史话
每日讯息!Weex原理及架构剖析
旅游专列来啦具体详细内容是什么
中国新能源汽车在欧洲火了:每10辆就有1辆来自中国
【时快讯】WebKit三件套(3):WebKit之Port篇
每日速看!HBase在进行模型设计时重点在什么地方?一张表中定义多少个Column Family最合适?为什么?
环球资讯:第136篇:Three.js基础入门动画API:setInterval 与 requestAnimationFrame的区别
程序员午休时健身猝死 被认定工伤 法院:属于在岗状态
比亚迪车主用木头手工还原汉EV:前后双电机 真能跑
每日速讯:WebKit三件套(1):WebKit之WebCore篇
焦点关注:C盘爆满的解决方法,不用删除文件,使用分区助手无损增加内存
简讯:招标活动法律保障工作实务指南 2016年版
锐龙7 7800X3D配A620主板 性能损失多少?实在没想到
天天微头条丨成都升温 千足虫满街爬:专家科普小心毒臭液
全球最大盗版电子书网站Z-Library被封后复活:路子更野了!要共享纸质书
速读:Steam排名第一!GTX 1650亮机卡火爆断货:RTX 2070紧急变身救场
【天天速看料】Vue——patch.ts【十四】
浏览器史话中chrome霸主地位的奠定与国产浏览器的割据混战
Vue开发规范
天天速递!只剩Windows版了!B站正式宣布UWP版停止维护
环球时讯:洛阳上演汉服秀 网友偶遇唐僧师徒四人坐地铁去“取经”
男子体内惊现小树苗!都长到5厘米高了
环球今亮点!或为AR眼镜新品!小米神秘“新礼物”明早10点正式亮相
今热点:解放军环台岛战备警巡和演习,专家:或成惩戒“台独”新模式
天天通讯!Linux常用操作命令总结
iOS Modern Collection View
线段树好题! P2824 [HEOI2016/TJOI2016]排序 题解
每日动态!小米寄修服务“史诗级”提升:新增进度可视化功能
天天资讯:第7章_InnoDB数据存储结构
天天快报!css过去及未来展望—分析css演进及排版布局的考量
每日关注!微信小程序 开发,uni-app 开发简介
今日报丨朗新科技:拟提前赎回“朗新转债”
今日观点!男子网购耐克鞋却挂着李宁的吊牌 网友:联名款?
数组的算法
超同年漫威大片近3倍!新海诚《铃芽之旅》国内票房达7亿
VUE-Antd开发,validate规则校验第一次为空,后面无论怎么输入都显示不可为空
环球新消息丨上海国创科技产业创新发展中心理事长黄岩:人工智能会像手机一样进入我们的日常生活
每日聚焦:青春回来了!电影《灌篮高手》流川枫角色预告出炉:4月20日国内上映
世界今亮点!暴雪战网遭遇DOSS攻击!多款游戏无法正常登录
世界聚焦:2023年3月随笔暨第1季度总结
世界热资讯!ASP.NET Core MVC 从入门到精通之接化发(一)
【全球聚看点】快速幂算法
私有化部署chatGPT,告别网络困扰
新车一超过60km/h就耳朵疼 车主:找了20多个人开都如此
Win11新版最快5月推送:微软确认Moment 3更新
【全球热闻】富二代开保时捷碰瓷:专挑开豪车酒驾的敲诈 “赚了”30多万
聚焦:五粮液董事长曾从钦:在“时与势”中勇担使命,在“稳与进”中拓展空间,在“个与众”中升级维度