Java 泛型(Generics)详解与使用
一、什么是 Java 泛型?
泛型(Generics)是 Java 1.5 引入的一项重要特性,主要用于 类型参数化,允许在类、接口和方法定义时使用 类型参数(Type Parameter),从而提高代码的复用性、类型安全性和可读性。
二、为什么需要泛型?
1. 解决类型安全问题
在没有泛型的时代,集合(如 ArrayList
)存储的是 Object
类型,容易发生类型转换异常。
import java.util.ArrayList;public class WithoutGenerics {public static void main(String[] args) {ArrayList list = new ArrayList(); // 没有指定类型list.add("Hello");list.add(100); // 这里插入了一个整数for (Object obj : list) {// 需要强制转换,否则无法使用 String 方法String str = (String) obj;System.out.println(str.toUpperCase()); // 运行时可能报 ClassCastException}}
}
运行时会抛出 ClassCastException
,因为 100
不能转换为 String
。
2. 使用泛型后,编译时即可发现错误
import java.util.ArrayList;public class WithGenerics {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>(); // 指定类型为 Stringlist.add("Hello");// list.add(100); // 编译时直接报错,避免了运行时异常for (String str : list) {System.out.println(str.toUpperCase());}}
}
- 类型安全:只能存储
String
,避免了ClassCastException
。 - 可读性好:不需要强制类型转换。
三、泛型的基本用法
1. 泛型类
泛型类在定义时,使用 类型参数(T) 来表示类中可以使用的类型。
// 定义一个泛型类
class Box<T> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}public class GenericClassExample {public static void main(String[] args) {Box<String> stringBox = new Box<>(); // 指定 T 为 StringstringBox.setItem("Hello");System.out.println(stringBox.getItem());Box<Integer> intBox = new Box<>(); // 指定 T 为 IntegerintBox.setItem(100);System.out.println(intBox.getItem());}
}
类型参数常见约定:
T
(Type):表示任意类类型E
(Element):集合中的元素类型K
(Key):键V
(Value):值
2. 泛型方法
泛型方法可以在 普通类或泛型类 中定义,方法的泛型参数只在方法内部生效。
class Util {// 泛型方法public static <T> void print(T data) {System.out.println(data);}
}public class GenericMethodExample {public static void main(String[] args) {Util.print("Hello");Util.print(123);Util.print(45.6);}
}
- 需要声明在方法返回值之前
- 泛型方法可以独立于类的泛型类型
3. 泛型接口
泛型接口通常用于 定义通用的操作,如数据存储、服务层 API。
// 定义泛型接口
interface Repository<T> {void save(T data);T get();
}// 实现泛型接口
class StringRepository implements Repository<String> {private String data;@Overridepublic void save(String data) {this.data = data;}@Overridepublic String get() {return data;}
}public class GenericInterfaceExample {public static void main(String[] args) {Repository<String> repo = new StringRepository();repo.save("Hello");System.out.println(repo.get());}
}
也可以使用 泛型类 实现泛型接口:
class GenericRepository<T> implements Repository<T> {private T data;@Overridepublic void save(T data) {this.data = data;}@Overridepublic T get() {return data;}
}
四、泛型的高级用法
1. 泛型的通配符
通配符 ? 代表不确定的类型,主要用于:
- 限定方法参数,使其接受不同的泛型类型。
- 保证类型安全,避免强制转换。
(1)? extends T 上界通配符
限制为 T
及其子类,适用于只 读取数据 的场景。
import java.util.List;public class WildcardExample {public static void printNumbers(List<? extends Number> list) {for (Number n : list) {System.out.println(n);}}public static void main(String[] args) {List<Integer> intList = List.of(1, 2, 3);List<Double> doubleList = List.of(1.1, 2.2, 3.3);printNumbers(intList);printNumbers(doubleList);}
}
- 允许
Integer
和Double
作为Number
的子类传入。 - 不能往 list 里添加元素,否则会引发
编译错误
,因为? extends Number
可能是Integer
或Double
,不确定具体类型。
(2)? super T 下界通配符
限制为 T
及其 父类,适用于 写入数据 的场景。
import java.util.List;
import java.util.ArrayList;public class SuperWildcardExample {public static void addNumbers(List<? super Integer> list) {list.add(10);list.add(20);}public static void main(String[] args) {List<Number> numberList = new ArrayList<>();addNumbers(numberList);System.out.println(numberList);}
}
- 允许
Integer
及其父类(如Number
)的List
作为参数。 - 可以往 list 里添加 Integer 类型的元素。
2. 泛型擦除(Type Erasure)
Java 的泛型是 编译时 作用的,编译后会进行 类型擦除,即所有泛型参数都会被 替换为 Object(或其上界类型)。
class Box<T> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}
编译后等价于:
class Box {private Object item;public void setItem(Object item) {this.item = item;}public Object getItem() {return item;}
}
影响:
- 不能直接创建泛型数组:
T[] array = new T[10]; // 编译错误
- 不能使用 instanceof 检测泛型类型:
if (obj instanceof Box<String>) // 编译错误
总结
特性 | 说明 |
---|---|
泛型类 | 通过 <T> 定义,可以使用不同类型创建实例 |
泛型方法 | 方法独立于类的泛型,可以使用不同类型参数 |
泛型接口 | 定义通用接口,支持泛型类实现 |
通配符 ? | ? extends T 适用于读取,? super T 适用于写入 |
泛型擦除 | 编译后泛型类型被擦除,限制了某些操作 |
注🚀:泛型是 Java 类型安全 和 代码复用 的重要特性,熟练掌握可以大幅提升开发效率!
相关文章:
Java 泛型(Generics)详解与使用
一、什么是 Java 泛型? 泛型(Generics)是 Java 1.5 引入的一项重要特性,主要用于 类型参数化,允许在类、接口和方法定义时使用 类型参数(Type Parameter),从而提高代码的复用性、类…...

七、Three.jsPBR材质与纹理贴图
1、PBR材质金属度和粗糙度 1、金属度metalness 金属度属性.metalness表示材质像金属的程度, 非金属材料,如木材或石材,使用0.0,金属使用1.0。 threejs的PBR材质,.metalness默认是0.5,0.0到1.0之间的值可用于生锈的金属外观 new THREE.MeshStandardMaterial({met…...

2024 ChatGPT大模型技术场景与商业应用视频精讲合集(45课).zip
2024ChatGPT大模型技术场景与商业应用视频精讲合集,共十三章,45课。 01. 第一章 ChatGPT:通用人工智能的典范 1.1 ChatGPT概述 .mp4 1.2 通用能力 .mp4 1.3 通用人工智能风口 .mp4 02. 第二章 大模型:ChatGPT的核心支撑 2.1 底层…...

Pytest之parametrize参数化
文章目录 1.前言2.单参数3.多参数4.字典形式5.parametrize 结合 ids 参数 1.前言 在 pytest 中,parametrize 是一个非常实用的装饰器,它允许你对测试函数进行参数化,即使用不同的参数组合多次运行同一个测试函数,从而更高效地进行…...
Python面试(八股)
1. 可变对象和不可变对象 (1). 不可变对象( Immutable Objects ) 不可变对象指的是那些一旦创建后其内容就不能被修改的对象。如果尝试修改不可变对象的内容,将会创建一个新的对象而不是修改原来的对象。常见的不可变类型包括: …...
2024年第十五届蓝桥杯大赛软件赛省赛Python大学A组真题解析《更新中》
文章目录 试题A: 拼正方形(本题总分:5 分)解析答案试题B: 召唤数学精灵(本题总分:5 分)解析答案试题C: 数字诗意解析答案试题D:回文数组试题A: 拼正方形(本题总分:5 分) 【问题描述】 小蓝正在玩拼图游戏,他有7385137888721 个2 2 的方块和10470245 个1 1 的方块,他需…...

湖仓一体概述
湖仓一体之前,数据分析经历了数据库、数据仓库和数据湖分析三个时代。 首先是数据库,它是一个最基础的概念,主要负责联机事务处理,也提供基本的数据分析能力。 随着数据量的增长,出现了数据仓库,它存储的是…...
【行政区划获取】
行政区划获取 获取2023年的行政区划,并以 编码: 省市区 格式保存为字典方便后续调用 注:网址可能会更新,根据最新的来 # 获取并保存行政区划代码 import requests from lxml import etree import jsondef fetch_html(url):""&quo…...

【深入剖析:机器学习、深度学习与人工智能的关系】
深入剖析:机器学习、深度学习与人工智能的关系 在当今数字化时代,人工智能(AI)、机器学习(ML)和深度学习(DL)这些术语频繁出现在各种科技报道和讨论中,它们相互关联又各…...

Docker 学习(一)
一、Docker 核心概念 Docker 是一个开源的容器化平台,允许开发者将应用及其所有依赖(代码、运行时、系统工具、库等)打包成一个轻量级、可移植的“容器”,实现 “一次构建,随处运行”。 1、容器(Container…...
flink web ui未授权漏洞处理
本文通过nginx代理的方式来处理未授权漏洞问题。 1.安装nginx 通过yum install nginx 2.添加账号和密码 安装htpasswd工具,yum install httpd-tools sudo htpasswd -c /etc/nginx/conf.d/.passwd flink # 需安装httpd-tools:ml-citation{ref"1,4" dat…...
【vue-echarts】——03.配置项---tooltip
文章目录 一、tooltip提示框组件二、显示结果一、tooltip提示框组件 提示框组件,用于配置鼠标滑过或点击图表时的显示框 代码如下 Demo3View.vue <template><div class="about">...

【弹性计算】弹性裸金属服务器和神龙虚拟化(二):适用场景
《弹性裸金属服务器》系列,共包含以下文章: 弹性裸金属服务器和神龙虚拟化(一):功能特点弹性裸金属服务器和神龙虚拟化(二):适用场景弹性裸金属服务器和神龙虚拟化(三&a…...
提升系统效能:从流量控制到并发处理的全面解析
在当今快速发展的数字时代,无论是构建高效的网络服务、管理海量数据,还是优化系统的并发处理能力,都是技术开发者和架构师们面临的重大挑战。本文集旨在深入探讨几个关键技术领域,包括用于网络通信中的漏桶算法与令牌桶算法的原理…...

计算机毕业设计SpringBoot+Vue.js贸易行业CRM系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

从头开始学SpringBoot—02ssmp整合及案例
《从头开始学SpringBoot》系列——第二篇 内容包括: 1)SpringBoot实现ssmp整合 2)SpringBoot整合ssmp的案例 目录 1.整合SSMP 1.1整合JUnit 1.2整合Mybatis 1.2.1导入对应的starter 1.2.2配置相关信息 1.2.3dao(或是mapper&…...
0301 leetcode - 1502.判断是否能形成等差数列、 682.棒球比赛、657.机器人能否返回原点
1502.判断是否能形成等差数列 题目 给你一个数字数组 arr 。 如果一个数列中,任意相邻两项的差总等于同一个常数,那么这个数列就称为 等差数列 。 如果可以重新排列数组形成等差数列,请返回 true ;否则,返回 false…...

Vulnhub靶机——AI-WEB-1
目录 一、实验环境 1.1 攻击机Kali 1.2 靶机下载 二、站点信息收集 2.1 IP扫描 2.2 端口扫描 2.3 目录扫描 三、漏洞利用 3.1 SQL注入 3.2 文件上传 四、权限提升 4.1 nc反弹连接 4.2 切换用户 一、实验环境 1.1 攻击机Kali 在虚拟机中安装Kali系统并作为攻击机 1.2 靶机下载 (…...

无人系统:未来科技的智能化代表
无人系统(Unmanned Systems)是指在不依赖人类直接干预的情况下,通过自主或远程控制方式完成任务的系统。随着科技的不断进步,特别是在人工智能、机器人学、传感技术、通信技术等领域的突破,无人系统在各行各业中得到了…...

在Docker中部署DataKit最佳实践
本文主要介绍如何在 Docker 中安装 DataKit。 配置和启动 DataKit 容器 登陆观测云平台,点击「集成」 -「DataKit」 - 「Docker」,然后拷贝第二步的启动命令,启动参数按实际情况配置。 拷贝启动命令: sudo docker run \--hostn…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...