当前位置: 首页 > news >正文

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、在使用泛型时,还需要注意以下几点:

  1. 泛型只能使用引用类型,不能使用基本类型;
  2. 不能创建泛型数组,但可以使用泛型集合;
  3. Java的泛型是通过类型擦除(type erasure)实现的,在编译期间会被转换为原始类型,因此无法在运行时获取泛型类型的具体信息;
  4. Java中的泛型不支持协变和逆变,但Java SE 8及以上版本引入了一些新特性来支持函数式编程中的协变和逆变。

二、泛型的优点

1、类型安全

泛型的主要目的是提高Java程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在非常高的层次上验证类型假设。没有泛型,这些假设就只能存在于系统开发人员的头脑中。

通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误就可以在编译时被捕获了,而不是在运行时当作ClassCastException展示出来。将类型检查从运行时挪到编译时有助于Java开发人员更早、更容易地找到错误,并可提高程序的可靠性。

2、消除强制类型转换

泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。尽管减少强制类型转换可以提高使用泛型类的代码的累赞程度,但是声明泛型变量时却会带来相应的累赞程度。在简单的程序中使用一次泛型变量不会降低代码累赞程度。但是对于多次使用泛型变量的大型程序来说,则可以累积起来降低累赞程度。所以泛型消除了强制类型转换之后,会使得代码加清晰和筒洁。

3、更高的效率

在非泛型编程中,将筒单类型作为Object传递时会引起Boxing(装箱)和Unboxing(拆箱)操作,这两个过程都是具有很大开销的。引入泛型后,就不必进行Boxing和Unboxing操作了,所以运行效率相对较高,特别在对集合操作非常频繁的系统中,这个特点带来的性能提升更加明显。

4、潜在的性能收益

泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,Java系统开发人员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的JVM的优化带来可能。

三、常见泛型字母含义

格式: 类名<字母列表>

  1. T Type表示类型
  2. K V 分辨表示键值对中的key value
  3. E 代表Element
  4. ?表示不确定的类型

四、使用泛型时的注意事项

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泛型的基本语法格式为&#xff1a;2、在使用泛型时&#xff0c;还需要注意以下几点&#xff1a;二、泛型的优点1、类型安全2、消除强制类型转换3、更高的效率4、潜在的性能收益三、常见泛型字母含义四、使用泛型时的注意事项五、泛型的使用1、泛型类2、…...

20230402英语学习

reasonable adj.合理的&#xff1b;通情达理的&#xff1b;明智的&#xff0c;理智的 abstract adj.抽象的&#xff0c;理论的 reflection n.反射; 映像, 倒影; 反映; 表达, 抒发; (长相等)酷似的人; 惟妙惟肖的事物; 深思; 考虑 instruction n.教授; 教导, 指导; 指示, 命令…...

Java知识复习(十七)SpringCloud

1、什么是微服务架构 微服务架构就是将单体的应用程序分成多个应用程序&#xff0c;这多个应用程序就成为微服务&#xff0c;每个微服务运行在自己的进程中&#xff0c;并使用轻量级的机制通信这些服务围绕业务能力来划分&#xff0c;并通过自动化部署机制来独立部署。这些服务…...

MySQL 数据库操作

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

Cesium更换地球背景

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

测试人员的瓶颈期

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

HTML5 <form> 标签

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

编译技术-词法理论

一、文法的种类 1.1 分类定义 Chomsky 文法定义&#xff1a; G(V,Vt,P,Z)G (V, V_t, P, Z)G(V,Vt​,P,Z)VVV&#xff1a;符号集合VtV_tVt​&#xff1a;终结符号集合PPP &#xff1a;有穷规则集合ZZZ&#xff1a;是被符号&#xff0c;不能是终结符 关于不同文法的区别 类型…...

【20】核心易中期刊推荐——计算机科学电子通信(EI索引)

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…...

Vue 3.0 风格指南 2

#元素 attribute 的顺序推荐 元素 (包括组件) 的 attribute 应该有统一的顺序。 这是我们为组件选项推荐的默认顺序。它们被划分为几大类&#xff0c;所以你也能知道新添加的自定义 attribute 和指令应该放到哪里。 定义 (提供组件的选项) is列表渲染 (创建多个变化的相同元素…...

ChatGPT遭多国调查,OpenAI凌晨就安全问题发文,GPT-5要暂缓?

最近&#xff0c;意大利宣布禁用 ChatGPT&#xff0c;因为 OpenAI 违反了意大利相关的隐私规则和数据保护法&#xff0c;出现了用户数据丢失情况&#xff0c;而且未向用户告知。 消息出来后&#xff0c;德国、法国、爱尔兰、西班牙等国的监管部门都表示正在密切关注 ChatGPT 的…...

网络安全书籍推荐

网络安全书籍推荐 &#xff0c;对于网络安全的初学者来说&#xff0c;能很好的选择教材&#xff0c;鉴于只有英文版&#xff0c;我尝试翻译成中文以供参考&#xff0c;初次翻译&#xff0c;翻译的不好请见谅。 标题注解技术等级The Art of Software Security Assessment软件安…...

【独家】华为OD机试 - 狼羊过河 or 羊、狼、农夫过河(C 语言解题)

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:狼羊过河 or 羊、狼、农夫过河…...

东八区的 springboot 如何配置序列化

东八区的 springboot &#x1f69e;使用SpringBoot默认配置自定义配置类自定义 ObjectMapper自定义序列化器总结我接受它的苦&#xff0c;它的灰暗&#xff0c;它的刺&#xff0c;因为总会过去&#xff0c;我的花会开&#xff0c;生活也会慢慢拥抱我 使用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,真是砂纸擦屁股,给我露了一手啊

​上周我们公司的绩效面谈全部结束了&#xff0c;每年到这个时间点就是打绩效的时候了&#xff0c;对于职场打工人来说绩效绝对是最重要的事情之一&#xff0c;原因也很简单&#xff1a;奖金、晋升、涨薪都和它有关系。 比如下面这个美团员工在脉脉上的自曝就很凄凉&#xff1…...

真题详解(计算机总线)-软件设计(四十五)

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

剪格子

[蓝桥杯 2013 省 A] 剪格子 题目描述 如图 111 所示&#xff0c;333\times 333 的格子中填写了一些整数。 我们沿着图中的红色线剪开&#xff0c;得到两个部分&#xff0c;每个部分的数字和都是 606060。 本题的要求就是请你编程判定&#xff1a;对给定的 mnm\times nmn 的格…...

【Nowcoder-BC146.添加逗号 -OR63.删除公共字符】

Nowcoder-BC146.-OR63.Nowcoder-BC146.添加逗号Nowcoder-OR63.删除公共字符Nowcoder-BC146.添加逗号 题目&#xff1a;对于一个较大的整数 N(1<N<2,000,000,000) 比如 980364535&#xff0c;我们常常需要一位一位数这个数字是几位数&#xff0c;但是如果在这个数字每三位…...

能自动摊铺施工的公路滑模机多少钱一台

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

ChatGPT热潮下,因生成式AI失业的人出现,我成了第一批失业的人

近几个月来&#xff0c;越来越多的知名人士预计&#xff0c;年内大热的ChatGPT有望掀起一场新的工业革命。而纵观历史&#xff0c;历次工业革命往往会深远改变当时的社会结构——从机械织布机到内燃机再到第一台计算机&#xff0c;新技术的出现总是会引起人们对于被机器取代的恐…...

TypeScript01-基础知识

基础类型 boolean 类型 let isDone: boolean false; // ES5&#xff1a;var isDone false;number 类型 let count: number 10; // ES5&#xff1a;var count 10;string 类型 let name: string "semliker"; // ES5&#xff1a;var name semlinker;Symbol 类…...

【Redis学习】Redis安装配置

Linux 安装环境必须先具备gcc编译环境 版本选择 查看自己redis版本的命令 安全Bug按照官网提示&#xff0c;升级成为6.0.8及以上 目前建议都需要升级到6.0.8版本以上 本次我们用Redis7.0 Redis7安装步骤 下载获得redis-7.0.0.tar.gz后将它放入Linux目录/opt /opt目录下解…...

leetcode160:相交链表

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后…...

基于Prometheus的jvm监控指标详解

使用Prometheus 监控Springboot应用参考 Prometheus Operator实战—— Prometheus、Alertmanager、Grafana 监控Springboot服务 下面来看看jvm的监控指标 # HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds. # TYPE jvm_gc_collection…...

C程序设计语言基础

机器语言与高级语言 计算机硬件只能够识别电平信号&#xff0c;正电平或负电平&#xff0c;计算机的的各种按钮触发各种电平与计算机交互。随着随着操作系统的发展&#xff0c;人们用1&#xff0c;0分别表示正电平和负电平&#xff0c;并由0&#xff0c;1所组成的一系列指令指…...

构建同一局域网下文件共享网页

首先&#xff0c;我会将这个内容分成以下步骤&#xff1a; 目录 1. 安装必要的软件和工具 2. 搭建本地服务器 3. 编写账号系统和登录页面 4. 实现多人登录 5. 实现文件上传和共享功能 以下是每个步骤的详细说明和代码示例。 1. 安装必要的软件和工具 为了完成这个项目&…...

程序员未来是不是会大量失业?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 会&#xff0c;但是主要原因并不是来自最近爆火的AIGC。 生成式AI对比与传统的工具的确很强大&#xff0c;但是要说替代某种工作岗位还为时尚早。最近铺天盖地的相关推文&#xff0c;热度一波未平又起…...

解密普元大文件传输平台新版本21种特性

本文主要介绍大文件传输平台及其传输特性&#xff0c;以平台版本升级为切入点&#xff0c;探讨大文件传输平台对多种传输场景的支持及部署管控方面能力的增强。目 录01 普元大文件传输平台‍‍02 普元文件传输平台新版本特性‍‍‍‍‍‍03 信创项目案例‍‍04 总结01普元大…...

每日一问-ChapGPT-20230406-中医基础-脉诊

文章目录每日一问-ChapGPT系列起因每日一问-ChapGPT-20230406-中医基础-脉诊脉诊脉诊的左右手脉诊拓展01沉脉:02迟脉:03促脉:04代脉:05动脉:06短脉:07伏脉:08浮脉:09革脉:10洪脉:11滑脉:12缓脉:13疾脉:14结脉:15紧脉:16芤脉:17散脉:18牢脉:19弦脉:20弱脉:21濡脉:22细脉:23微脉:…...