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…...
香橙派Zero3无屏幕配网新玩法:用ESP32-C3蓝牙模块搞定WiFi连接(附完整代码)
香橙派Zero3无屏幕配网新玩法:用ESP32-C3蓝牙模块搞定WiFi连接(附完整代码) 在物联网和边缘计算项目中,无头设备(Headless Device)的网络配置一直是个棘手问题。想象一下:你刚拿到一块香橙派Zer…...
别再死记公式了!用Cadence仿真带你直观理解比较器的增益、失调与噪声
Cadence实战:用仿真可视化比较器的增益、失调与噪声特性 刚接触模拟电路设计时,那些复杂的公式和抽象概念总让人头疼。比较器的增益、失调电压、噪声——这些名词在教科书上看起来冰冷生硬,但当你第一次在Cadence Virtuoso中看到它们如何真实…...
嵌入式与复杂系统安全开发实战:从威胁建模到安全编码的十大核心实践
1. 项目概述:为什么安全开发不再是“可选项”?干了十几年软件开发,从早期的桌面应用到后来的Web服务,再到近几年深度参与的嵌入式系统,我最大的感触就是:安全这件事,已经从“锦上添花”变成了“…...
你的方差分析做对了吗?避开SPSS中ANOVA的5个经典坑(从数据准备到结果报告)
你的方差分析做对了吗?避开SPSS中ANOVA的5个经典坑(从数据准备到结果报告) 在科研论文和市场调研中,方差分析(ANOVA)是最常用的统计方法之一。许多研究者虽然掌握了SPSS的基本操作,却在结果报告…...
CANN/pypto CODEGEN组件错误码
CODEGEN 组件错误码 【免费下载链接】pypto PyPTO(发音: pai p-t-o):Parallel Tensor/Tile Operation编程范式。 项目地址: https://gitcode.com/cann/pypto 范围:F6XXXX本文档说明 CODEGEN 组件的错误码定义、场景说明与排…...
Lovable框架实战速成:3天掌握UI动效、状态管理与热重载调试全流程
更多请点击: https://intelliparadigm.com 第一章:Lovable框架核心理念与开发环境搭建 Lovable 是一个以开发者体验(DX)为第一优先级的现代 Go Web 框架,其核心理念可凝练为三个关键词:可读性(…...
工具调用优化:减少API延迟对Agent性能的影响
《工具调用优化全指南:彻底解决API延迟拖累大模型Agent性能的痛点》 副标题:从原理到落地,覆盖缓存、并行、调度、轻量化改造全链路可复现方案 第一部分:引言与基础 1.1 摘要/引言 你有没有遇到过这种场景:辛辛苦苦开发的智能Agent功能非常强大,能查订单、搜资料、算数…...
2026年HR推荐的10个专业简历模板网站,从模板到写法
2026年HR推荐的10个专业简历模板网站,从模板到写法写一份让HR眼前一亮的简历,是很多求职者遇到的难题。模板选什么风格、内容怎么写才专业、怎么排版才不会被系统筛掉——这些问题常常让人头疼。这篇文章整理了10个HR推荐的专业简历模板网站,…...
[智能体-7]:业务数据序列化为 JSON 字符串 完整示例
一、概念序列化:把程序里的对象 / 字典 / 实体数据 → 转换成JSON 格式字符串,用于网络传输、接口请求、存储。反序列化:JSON 字符串 → 还原成程序可直接使用的数据对象。二、Python 示例(最常用,对接 OpenAI / 大模型…...
YCWebView架构设计与源码解析:面向对象设计思想与模块化实现
YCWebView架构设计与源码解析:面向对象设计思想与模块化实现 【免费下载链接】YCWebView 基于腾讯x5开源库,提高webView开发效率,大概要节约你百分之六十的时间成本。该案例支持处理js的交互逻辑且无耦合、同时暴露进度条加载进度、可以监听异…...
