49天精通Java,第14天,Java泛型方法的定义和使用
目录
- 一、基本介绍
- 1、Java泛型的基本语法格式为:
- 2、在使用泛型时,还需要注意以下几点:
- 二、泛型的优点
- 1、类型安全
- 2、消除强制类型转换
- 3、更高的效率
- 4、潜在的性能收益
- 三、常见泛型字母含义
- 四、使用泛型时的注意事项
- 五、泛型的使用
- 1、泛型类
- 2、泛型接口
- 3、泛型通配符
- 4、泛型方法
- 六、Java泛型上下边界
- 1、上边界
- 2、下边界
- 七、泛型擦除
大家好,我是哪吒。
一、基本介绍
Java泛型(Generics)是一种强类型约束机制,用于在编译时检查代码的类型安全性。它可以让程序员定义一些具有通用性的类、接口和方法,以便在后续使用中可以适用于不同的数据类型。
1、Java泛型的基本语法格式为:
public class Student<T> {private T value;public void setValue(T value) {this.value = value;}public T getValue() {return value;}
}
在上面的示例代码中,我们定义了一个泛型类MyClass,其中T表示类型参数(Type Parameter)。在类的成员变量和方法中,我们都可以使用T来代替实际的数据类型,从而实现对不同数据类型的支持。
通过使用泛型,可以大大提高代码的可读性和类型安全性,并且避免了需要进行强制类型转换的繁琐操作。同时,泛型还可以提高代码的重复利用率,减少代码量,提高开发效率。
2、在使用泛型时,还需要注意以下几点:
- 泛型只能使用引用类型,不能使用基本类型;
- 不能创建泛型数组,但可以使用泛型集合;
- Java的泛型是通过类型擦除(type erasure)实现的,在编译期间会被转换为原始类型,因此无法在运行时获取泛型类型的具体信息;
- Java中的泛型不支持协变和逆变,但Java SE 8及以上版本引入了一些新特性来支持函数式编程中的协变和逆变。
二、泛型的优点
1、类型安全
泛型的主要目的是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在非常高的层次上验证类型假设。没有泛型,这些假设就只能存在于系统开发人员的头脑中。
通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误就可以在编译时被捕获了,而不是在运行时当作ClassCastException展示出来。将类型检查从运行时挪到编译时有助于Java开发人员更早、更容易地找到错误,并可提高程序的可靠性。
2、消除强制类型转换
泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。尽管减少强制类型转换可以提高使用泛型类的代码的累赞程度,但是声明泛型变量时却会带来相应的累赞程度。在简单的程序中使用一次泛型变量不会降低代码累赞程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低累赞程度。所以泛型消除了强制类型转换之后,会使得代码加清晰和筒洁。
3、更高的效率
在非泛型编程中,将筒单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销的。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作非常频繁的系统中,这个特点带来的性能提升更加明显。
4、潜在的性能收益
泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,Java系统开发人员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的JVM的优化带来可能。
三、常见泛型字母含义
格式: 类名<字母列表>
- T Type表示类型
- K V 分辨表示键值对中的key value
- E 代表Element
- ?表示不确定的类型
四、使用泛型时的注意事项
1、在定义一个泛型类时,在“<>”之间定义形式类型参数,例如:“class TestGen<K,V>”,其中“K”,“V”不代表值,而是表示类型。
2、实例化泛型对象时,一定要在类名后面指定类型参数的值(类型),一共要有两次书写。
3、使用泛型时,泛型类型必须为引用数据类型,不能为基本数据类型,Java中的普通方法,构造方法,静态方法中都可以使用泛型,方法使用泛型之前必须先对泛型进行声明,可以使用任意字母,一般都要大写。
4、不可以定义泛型数组。
5、在static方法中不可以使用泛型,泛型变量也不可以用static关键字来修饰。
6、根据同一个泛型类衍生出来的多个类之间没有任何关系,不可以互相赋值。
7、泛型只在编译器有效
五、泛型的使用
泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法
1、泛型类
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Student<T> {//key这个成员变量的类型为T,T的类型由外部指定private T key;//泛型构造方法形参key的类型也为T,T的类型由外部指定public Student(T key){this.key = key;}//泛型方法getKey的返回值类型为T,T的类型由外部指定public T getKey(){return key;}public static void main(String[] args) {//泛型的类型参数只能是类类型(包括自定义类),不能是简单类型//传入的实参类型需与泛型的类型参数类型相同,即为Integer.Student<Integer> student = new Student<Integer>(123456);//传入的实参类型需与泛型的类型参数类型相同,即为String.Student<String> str= new Student<String>("哪吒编程");System.out.println("泛型测试,key is "+student .getKey());System.out.println("泛型测试,key is "+str.getKey());}
}
泛型参数就是随便传的意思!
Student student1 = new Student("哪吒编程");
Student student2 = new Student(4444);
Student gstudent3 = new Student(55.55);
Student student4 = new Student(false);
2、泛型接口
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中,可以看一个例子:
//定义一个泛型接口
public interface Generator<T> {public T next();
}
当实现泛型接口的类,未传入泛型实参时:
/*** 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中* 即:class FruitGenerator<T> implements Generator<T>{* 如果不声明泛型,如:class FruitGenerator implements Generator<T>,编译器会报错:"Unknown class"*/
class FruitGenerator<T> implements Generator<T>{@Overridepublic T next() {return null;}
}
当实现泛型接口的类,传入泛型实参时:
package javase.genericity;import java.util.Random;public class FruitGenerator implements Generator<String>{String[] fruits = new String[]{"apple","banana","Pear"};@Overridepublic String next() {Random random = new Random();System.out.println(fruits[random.nextInt(3)]);return fruits[random.nextInt(3)];}public static void main(String[] args) {FruitGenerator ff = new FruitGenerator();ff.next();}
}
3、泛型通配符
Java泛型通配符(wildcard)用于表示某个类型参数可以接受任意类型的实参,采用“?”作为通配符。
在使用泛型时,有时候需要定义一个方法或类,能够接受多种类型的参数。这时就可以使用泛型通配符来实现。Java中有三种泛型通配符:extends、super和无限制通配符。
(1)extends通配符
表示该类型参数是某个特定类型的子类或本身,可以接受该类型及其子类的实参。
例如:
public void printList(List<? extends Number> list) {for (Number n : list) {System.out.println(n);}
}
(2)super通配符
表示该类型参数是某个特定类型的超类或本身,可以接受该类型及其父类的实参。
例如:
public void addList(List<? super Integer> list) {list.add(1);list.add(2);list.add(3);
}
(3)无限制通配符
表示该类型参数可以接受任意类型的实参。
例如:
public void showList(List<?> list) {for (Object o : list) {System.out.println(o);}
}
泛型通配符只能用于方法参数、返回值和局部变量等地方,不能用于类的定义中。同时,在使用泛型通配符时应该遵循PECS原则(Producer Extends, Consumer Super),即生产者使用extends通配符,消费者使用super通配符,以保证类型安全。
4、泛型方法
Java中的泛型方法是指在方法名称前加上的方法,它可以接受任意类型的参数。
下面是一个简单的示例:
public class GenericExample { public <T> T[] createArray(T[] array) { return array; }
}
在上面的示例中,createArray方法接受一个T[]类型的参数,并返回一个T[]类型的数组。在方法体中,我们可以使用array参数来创建一个T[]类型的数组。
需要注意的是,泛型方法的参数类型必须与方法体中的参数类型相同。如果方法体中的参数类型与方法名称前加上的参数类型不同,则编译器会报错。
六、Java泛型上下边界
Java泛型上下边界是指在定义泛型时,我们可以通过指定类型参数的上限或下限来限制实际参数的类型范围。
1、上边界
使用extends关键字来限制类型参数的上限,表示该类型参数必须是指定类型的子类或本身。
public class MyClass<T extends Number> {// 类定义
}
在上面的示例中,我们使用extends关键字将类型参数T的上限指定为Number类,表示只有Number及其子类才能作为实参传递进来。
2、下边界
使用super关键字来限制类型参数的下限,表示该类型参数必须是指定类型的超类或本身。
public class MyClass<T super Integer> {// 类定义
}
在上面的示例中,我们使用super关键字将类型参数T的下限指定为Integer类,表示只有Integer及其父类才能作为实参传递进来。
需要注意的是,在使用上下边界时,如果同时指定了上下边界,则应该先指定下边界再指定上边界。同时,在使用上下边界时也需要遵循PECS原则(Producer Extends, Consumer Super),即生产者使用extends通配符,消费者使用super通配符,以保证类型安全。
七、泛型擦除
Java泛型擦除是指在Java编译器将泛型类型的代码编译成字节码时,会将所有泛型类型的信息删除,以避免运行时带来的额外开销。
在Java中,泛型只是一种编译时检查机制,并不会影响程序的运行时行为。在编译期间,Java编译器会将泛型类型擦除为原始类型,并在必要时插入强制类型转换语句。
List<String> list = new ArrayList<>();
list.add("哪吒编程");
String s = list.get(0);
然我们使用了泛型类型List,但在编译后,它会被擦除为List,因此get()方法返回的实际类型为Object,并且需要进行强制类型转换才能得到String类型的值。
由于泛型擦除的存在,导致在运行时无法获取泛型类型的具体信息,因此在使用反射和类型转换等相关操作时需要格外小心,以避免产生类型安全问题。
需要注意的是,在Java SE 8及以上版本中,引入了新的特性来支持对函数式接口中的泛型类型进行推断和获取,以及在局部变量初始化时使用类型推断,从而进一步提高了泛型的灵活性和可读性。
🏆本文收录于,Java基础教程系列。
目前已经700+订阅,CSDN最强Java专栏,包含全部Java基础知识点、Java8新特性、Java集合、Java多线程、Java代码实例,理论结合实战,实现Java的轻松学习。
🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。
相关文章:

49天精通Java,第14天,Java泛型方法的定义和使用
目录一、基本介绍1、Java泛型的基本语法格式为:2、在使用泛型时,还需要注意以下几点:二、泛型的优点1、类型安全2、消除强制类型转换3、更高的效率4、潜在的性能收益三、常见泛型字母含义四、使用泛型时的注意事项五、泛型的使用1、泛型类2、…...
20230402英语学习
reasonable adj.合理的;通情达理的;明智的,理智的 abstract adj.抽象的,理论的 reflection n.反射; 映像, 倒影; 反映; 表达, 抒发; (长相等)酷似的人; 惟妙惟肖的事物; 深思; 考虑 instruction n.教授; 教导, 指导; 指示, 命令…...
Java知识复习(十七)SpringCloud
1、什么是微服务架构 微服务架构就是将单体的应用程序分成多个应用程序,这多个应用程序就成为微服务,每个微服务运行在自己的进程中,并使用轻量级的机制通信这些服务围绕业务能力来划分,并通过自动化部署机制来独立部署。这些服务…...

MySQL 数据库操作
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、关系模型二、数据库的操作 创建数据库查看数据库选择数据库删除数据库三、MySQL 数据库命名规范总结一、关系模型 关系数据库是建立在关系模型上的。而关系模…...

Cesium更换地球背景
设置背景图片 #cesiumContainer {width: 100%;height: 100%;background-image: url("/assets/image/背景.png"); }设置渲染, 用来去掉地球表面的大气效果的黑圈问题 this.viewer new Cesium.Viewer("cesiumContainer", {......// 设置渲染orderIndepe…...

测试人员的瓶颈期
测试人员的瓶颈期 做测试久了,会在所难免地碰到职业瓶颈期,这很正常,从事任何职业的工作人员都会遇到,关键是要看你如何去克服它。对优秀的软件测试人员来讲,除了要具备全面的技能、丰富的经验、良好的心理素质&#x…...

HTML5 <form> 标签
HTML5 <form> 标签 实例 带有两个输入字段和一个提交按钮的 HTML 表单: <form action"demo_form.php" method"get">First name: <input type"text" name"fname"><br>Last name: <input type&qu…...

编译技术-词法理论
一、文法的种类 1.1 分类定义 Chomsky 文法定义: G(V,Vt,P,Z)G (V, V_t, P, Z)G(V,Vt,P,Z)VVV:符号集合VtV_tVt:终结符号集合PPP :有穷规则集合ZZZ:是被符号,不能是终结符 关于不同文法的区别 类型…...

【20】核心易中期刊推荐——计算机科学电子通信(EI索引)
🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…...
Vue 3.0 风格指南 2
#元素 attribute 的顺序推荐 元素 (包括组件) 的 attribute 应该有统一的顺序。 这是我们为组件选项推荐的默认顺序。它们被划分为几大类,所以你也能知道新添加的自定义 attribute 和指令应该放到哪里。 定义 (提供组件的选项) is列表渲染 (创建多个变化的相同元素…...

ChatGPT遭多国调查,OpenAI凌晨就安全问题发文,GPT-5要暂缓?
最近,意大利宣布禁用 ChatGPT,因为 OpenAI 违反了意大利相关的隐私规则和数据保护法,出现了用户数据丢失情况,而且未向用户告知。 消息出来后,德国、法国、爱尔兰、西班牙等国的监管部门都表示正在密切关注 ChatGPT 的…...
网络安全书籍推荐
网络安全书籍推荐 ,对于网络安全的初学者来说,能很好的选择教材,鉴于只有英文版,我尝试翻译成中文以供参考,初次翻译,翻译的不好请见谅。 标题注解技术等级The Art of Software Security Assessment软件安…...
【独家】华为OD机试 - 狼羊过河 or 羊、狼、农夫过河(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:狼羊过河 or 羊、狼、农夫过河…...
东八区的 springboot 如何配置序列化
东八区的 springboot 🚞使用SpringBoot默认配置自定义配置类自定义 ObjectMapper自定义序列化器总结我接受它的苦,它的灰暗,它的刺,因为总会过去,我的花会开,生活也会慢慢拥抱我 使用SpringBoot默认配置 S…...

论文阅读_LLaMA
论文信息 number headings: auto, first-level 2, max 4, _.1.1 name_en: LLaMA: Open and Efficient Foundation Language Models name_ch: LLaMA: 开放高效的基础语言模型 paper_addr: https://arxiv.org/abs/2302.13971 doi: https://doi.org/10.48550/arXiv.2302.13971 da…...

腾讯空降测试工程师,绩效次次拿S,真是砂纸擦屁股,给我露了一手啊
上周我们公司的绩效面谈全部结束了,每年到这个时间点就是打绩效的时候了,对于职场打工人来说绩效绝对是最重要的事情之一,原因也很简单:奖金、晋升、涨薪都和它有关系。 比如下面这个美团员工在脉脉上的自曝就很凄凉࿱…...

真题详解(计算机总线)-软件设计(四十五)
真题详解(二维数组)-软件设计(四十四)https://blog.csdn.net/ke1ying/article/details/130023062 1、2016年下半年 解析: A选项,当B中的两个结束都到达,会转到C2,因为C2没有事件&a…...

剪格子
[蓝桥杯 2013 省 A] 剪格子 题目描述 如图 111 所示,333\times 333 的格子中填写了一些整数。 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 606060。 本题的要求就是请你编程判定:对给定的 mnm\times nmn 的格…...
【Nowcoder-BC146.添加逗号 -OR63.删除公共字符】
Nowcoder-BC146.-OR63.Nowcoder-BC146.添加逗号Nowcoder-OR63.删除公共字符Nowcoder-BC146.添加逗号 题目:对于一个较大的整数 N(1<N<2,000,000,000) 比如 980364535,我们常常需要一位一位数这个数字是几位数,但是如果在这个数字每三位…...

能自动摊铺施工的公路滑模机多少钱一台
滑模机是能在公路施工现场进现场自动摊铺作业的设备,让路缘石经过设备制作一次性完成施工工序,整体成型一次完成。这样的使用流程整体包含了几个大的关键步骤,分别是测量后放置标示线-设备进场就位-原材料运输和供应-滑模机摊铺作业-后续伸缩…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...