【Java基础】泛型(一)-基础使用
本文以Java的官方文档为参考,辅以代码示例,尽可能详尽的叙述泛型的每一个特性
什么是泛型
泛型(Generics)也称为参数化类型(parameterized types),也就是将类型本身作为接口、类、方法中的参数,相应地声明泛型接口、泛型类、泛型方法,在具体调用时再传入类型参数。从而实现同一种接口、类、方法适用于不同的类型。
为什么要有泛型
- 代码重用
泛型程序设计,意味着代码可以针对不同类型重用,你不可能希望针对String和Integer分别编写一个ArrayList
- 编译时类型检查
Java5之前,如果想实现泛型就需要这样做:例如定义一个包含Object数组的ArrayList
List v = new ArrayList();
v.add("test"); // 不会做类型检查
Integer i = (Integer)v.get(0); // 运行时异常(Runtime error)
这里其实利用了多态,编译时对set操作不会做类型检查,也不会报get操作的异常。强转的错误在运行时才会抛异常(向下转型不安全)
如果一个错误没有被发现,那么系统会进入不可预知的状态,会产生更严重的后果,并且使得错误更难被发现,所以,一个鲁棒的系统应该尽可能早地和多地报告异常。这个哲学思想也可以叫做“故障导向安全原则”。
java5之后引入泛型,实现方式:加入类型参数,(类型本身作为一个参数),好处在于
- 更易读:代码会有很好的可读性,人们就知道ArrayList存的是什么类型
- 更安全:而且编译时set的时候会有类型检查,get的时候也不用手工强转了
泛型类
泛型类的声明和使用
假设有一个Box类,我希望可以set和get任意类型的object,在没有泛型机制时的定义如下:
public class Box {private Object object;public void set(Object object) { this.object = object; }public Object get() { return object; }
}
显然,如上节中提到,get方法调用时可能会出现运行时异常,因此我们利用泛型来实现Box类
首先,泛型类的定义格式如下:
class name<T1, T2, ..., Tn>
尖括号中是类型参数,可以被用在类中的任意位置,包括对象类型,方法入参类型,返回值类型。
由此,Box类的定义如下:
public class Box<T> {// T stands for "Type"private T t;public void set(T t) { this.t = t; }public T get() { return t; }
}
可以看出这里就是将原来Object类型全部换成了类型参数T
创建类对象,将T替换为实际的类型参数即可(就像给方法传参一样,将形参T变为实参Integer)
Box<Integer> integerBox = new Box<Integer>();
简化的使用方式:类型推断
Java 7之后可以利用类型推断,省略构造器后面的泛型:
Box<Integer> integerBox = new Box<>();
泛型接口
泛型接口的声明和使用
泛型接口与泛型类的定义大同小异,以一个简化的List接口为例
public interface List<E> {boolean add(E e);E get(int index);
}
实现或者继承泛型接口,有两种情况:
一种是不替换泛型形参E,即不指定具体的类型。这时类名后面必须也把泛型实参添加上,以ArrayList为例
public class ArrayList<E> extends AbstractList<E>implements List<E> { //ArrayList后面必须添加<E>boolean add(E e);E get(int index);
}
另一种就是替换泛型形参E。这时实现类中所有形参出现的地方必须替换为实参,例如我定义了一个只存String类型的StringArrayList
public class StringArrayList extends ArrayList<String> { boolean add(String e); //方法重写String get(int index);
}
泛型方法
泛型方法的声明和使用
泛型方法是带类型参数的方法,注意类型参数在修饰符后面,返回类型前面。
泛型方法的作用范围只在本方法中,因此可以作为方法入参类型,或者返回值类型
典型例子就是Arrays.asList方法(泛型方法其实在Collections, Arrays等工具类中应用的很广泛)
public static <T> List<T> asList(T... a) { //这里返回List<T>,其实就相当于T用在了泛型方法的返回值类型中return new ArrayList<>(a);
}
这时如何使用上面的泛型方法?有以下两种:
- 替换尖括号内的类型参数(相当于传参)
String[] stringArr = new String[]{"abc", "123", "opq"};
List<String> StringList = Arrays.<String>asList(stringArr);
- 编译器自行推断 一般我们在使用工具类的泛型方法时基本没见过上面的语法,其实编译器可以通过传入参数进行推断
List<String> StringList = Arrays.asList(stringArr);
注意事项:静态方法使用泛型
上面提到类型形参T可以用在类中的任意位置,但实际上不可以作为静态方法的入参和返回值类型,如果想让静态方法用到泛型,就得让静态方法自身变为泛型方法。
public class Box<T> {//这里Box后面的泛型<T>和静态方法的泛型<T>并不是一个类型public static <T> void show(T t){}
}
相关文章:
【Java基础】泛型(一)-基础使用
本文以Java的官方文档为参考,辅以代码示例,尽可能详尽的叙述泛型的每一个特性 什么是泛型 泛型(Generics)也称为参数化类型(parameterized types),也就是将类型本身作为接口、类、方法中的参数…...
学Python不会不知道NumPy计算包吧,带你五分钟看懂NumPy计算包
从今天我们就开始进入 Python 数据分析工具的教程。 前段时间数据分析和Python都讲了一点点,但是Python的数据库,讲的少了点,所以接下来就讲讲这些重要的常用数据库吧!!! Python 数据分析绝对绕不过的四个…...
积水内涝监测——埋入式积水终端设备介绍
一、设备概述 埋入式积水终端是针对城市内涝推出的积水信息监测采集设备,采用超声波传感技术,对积水的深度进行精确的测量。产品能够在低温、腐蚀环境下可靠运行本产品特别适用于智慧城市中,对城市道路、社区低洼处的积水进行实时监测上报到…...
Kafka的日志同步
首先介绍下LEO和HW LEO: 即LogEndOffset,表示该副本下次日志记录的偏移量HW:即HighWatermark,高水位线,是所有ISR副本集合中的LEO最小值上图中,如果此时三个副本都在ISR集合中,那么此时他们的LE…...
【Mybatis源码解析】mapper实例化及执行流程源码分析
文章目录简介环境搭建源码解析基础环境:JDK17、SpringBoot3.0、mysql5.7 储备知识:《【Spring6源码・AOP】AOP源码解析》、《JDBC详细全解》 简介 基于SpringBoot的Mybatis源码解析: 1.如何对mapper实例化bean 在加载BeanDefinition时&a…...
分布式文件管理系统(MinIO)
1.去中心化,每个点是对等的关系,通过Ngix对负载做均衡工作。 好处: 能够避免单点故障,将多块硬盘组成一个对象存储服务。 2. 使用纠删编码技术来保护数据,是一种回复丢失和损坏的数据的数学算法,他将数据分…...
Springcloud-配置中心config
一、添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId&…...
[项目篇] 音乐播放器开发报告
文章目录1. 项目描述:2. 项目上线展现:3. 项目具体实现:1. 登录2. 注册3.退出系统4.添加音乐4.1前后端交互约定4.2上传文件业务逻辑:4.3创建model包中的music类4.4在MusicMapper接口中,声明insertMusic抽象方法4.5在mybatis包中添…...
Spring Cloud Alibaba--gateway微服务详解之网关(二)
1、网关介绍 上篇对微服务中的nacos注册中心进行集成讲解。nacos主要作用是管理多服务之间复杂关系的组件。微服务是非常庞大且问题突出的架构,HTTP协议具有跨源资源共享 (CORS) Cross- Origin Resource Sharing机制,而处于安全考虑往往前端架构都会对跨…...
Zynq非VDMA方案实现视频3帧缓存输出,无需SDK配置,提供工程源码和技术支持
目录1、前言2、VDMA的不便之处3、FDMA取代VDMA实现视频缓存输出4、Vivado工程详解5、上板调试验证并演示6、福利:工程代码的获取1、前言 对于Zynq和Microblaze的用户而言,要想实现图像缓存输出,多半要使用Xilinx推荐的VDMA方案,该…...
血液透析过滤芯气密性检测装置中的高精度多段压力控制解决方案
摘要:针对目前血液过滤芯气密性检测过程中存在的自动化水平较低、多个检测压力之间需人工切换和压力控制精度较差的问题,为满足客户对高精度和自动化气密性检测的要求,本文提出了相应的解决方案。解决方案的主要特点是全过程的可编程压力控制…...
PDF加密如何批量解除?快来了解下这个方法
在现代办公环境中,PDF文档的使用非常普遍。然而,由于一些安全需求,有时候PDF文档会被加密,使得只有授权人员可以查看或修改它。但是,如果您需要对许多加密PDF文档进行操作,逐个解密这些文档可能非常费时费力…...
C++——哈希4|布隆过滤器
目录 布隆过滤器 完整代码 布隆过滤器应用 布隆过滤器的查找 布隆过滤器删除 布隆过滤器优点 布隆过滤器缺陷 布隆过滤器海量数据处理 布隆过滤器 位图只能映射整形,而对于字符串却无能为力。 把字符串用哈希算法转成整形,映射一个位置进行标…...
python冒号的用法总结
一维数组 1. 单个冒号的情况 1.1 写完整的情况下 单个冒号的情况下,对数组的遍历操作是从前向后操作。如:arr[a:b] ,冒号前的a含义是从a开始遍历,冒号后的b含义是到b截止(不包括b)。 arr [1, 2, 3, 4,…...
面试题整理
面试题整理 一、Java基础 1、Java 语言有哪些特点 简单易学; 面向对象(封装,继承,多态); 平台无关性( Java 虚拟机实现平台无关性); 支持多线程( C 语言…...
C语言深度解剖-关键字(7)
目录 switch case 语句 理解: 补充: 深入理解: default 语句: case语句: 总结: do、while、for 关键字 while for do while 各种死循环方法: while for do while getchar 写在…...
利用JavaScript编写Python内置函数查询工具
最近我开始学习Python编程语言,我发现Python拥有非常丰富的内置函数,可以用来实现各种不同的功能。但是每当我需要查找一个内置函数时,我总是需要联网使用搜索引擎进行查询。这种方式不仅费时费力,而且需要联网,很不方…...
【MySQL进阶】SQL优化
😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享Java相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页…...
最新版海豚调度dolphinscheduler-3.1.3配置windows本地开发环境
0 说明 本文基于最新版海豚调度dolphinscheduler-3.1.3配置windows本地开发环境,并在windows本地进行调试和开发 1 准备 1.1 安装mysql 可以指定为windows本地mysql,也可以指定为其他环境mysql,若指定为其他环境mysql则可跳过此步。 我这…...
csv文件完整操作总结
csv文件完整操作总结 1.概述 csv 模块主要用于处理从电子数据表格Excel或数据库中导入到文本文件的数据,通常简称为 comma-separated value (CSV)格式因为逗号用于分离每条记录的各个字段。 2.读写操作 2.1.测试数据 创建一个test.csv文…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
