目录

一、泛型的基本概念

为什么需要泛型?

二、泛型类与泛型接口

【1】定义泛型类

【2】定义泛型接口

三、泛型方法

四、泛型通配符

【1】无界通配符(?)

【2】上界通配符(? extends T)

【3】下界通配符(? super T)

五、类型擦除

六、泛型的最佳实践

七、总结


        泛型是 Java SE 5 引入的重要特性,它提供了编译时类型安全检测机制,允许在编译时检测到非法的类型转换,从而提高代码的安全性和可读性。本文将全面解析 Java 泛型的核心概念、使用方法及高级特性。


一、泛型的基本概念

        泛型(Generics)本质是参数化类型,即允许在定义类、接口和方法时使用类型参数,在使用时指定具体类型。这种机制使代码可以应用于多种数据类型,同时保证类型安全。

为什么需要泛型?

在没有泛型的情况下,我们需要使用强制类型转换,这可能导致运行时错误:

// 无泛型的情况
List list = new ArrayList();
list.add("Hello");
String s = (String) list.get(0); // 需要强制转换
list.add(100); // 可以添加整数
String s2 = (String) list.get(1); // 运行时抛出ClassCastException

使用泛型后:

// 有泛型的情况
List<String> list = new ArrayList<>();
list.add("Hello");
String s = list.get(0); // 无需强制转换
list.add(100); // 编译时直接报错,避免运行时异常

二、泛型类与泛型接口

【1】定义泛型类

泛型类是在类定义时声明了类型参数的类,语法格式如下:

public class Box<T> {private T value;public T getValue() {return value;}public void setValue(T value) {this.value = value;}
}

其中,T是类型参数,可以是任意标识符,通常使用:

  • T:Type(类型)
  • E:Element(元素)
  • K:Key(键)
  • V:Value(值)
  • N:Number(数字)

使用泛型类:

Box<String> stringBox = new Box<>();
stringBox.setValue("Hello");
String str = stringBox.getValue();Box<Integer> intBox = new Box<>();
intBox.setValue(100);
int num = intBox.getValue();

【2】定义泛型接口

泛型接口的定义与泛型类类似:

public interface Generator<T> {T generate();
}// 实现泛型接口
public class NumberGenerator implements Generator<Integer> {@Overridepublic Integer generate() {return new Random().nextInt();}
}

三、泛型方法

泛型方法是在方法声明中定义类型参数的方法,它可以在普通类或泛型类中定义:

public class GenericMethodExample {// 泛型方法public <T> T getFirstElement(List<T> list) {if (list != null && !list.isEmpty()) {return list.get(0);}return null;}// 使用泛型方法public static void main(String[] args) {GenericMethodExample example = new GenericMethodExample();List<String> strList = Arrays.asList("A", "B", "C");String firstStr = example.getFirstElement(strList);List<Integer> intList = Arrays.asList(1, 2, 3);Integer firstInt = example.getFirstElement(intList);}
}

静态方法无法访问类的类型参数,因此静态泛型方法必须自己声明类型参数:

public class StaticGenericMethod {// 静态泛型方法public static <T> void printElement(T element) {System.out.println(element);}
}

四、泛型通配符

泛型通配符用于表示未知类型,主要有三种形式:

【1】无界通配符(?)

表示可以是任意类型:

public void printList(List<?> list) {for (Object obj : list) {System.out.println(obj);}
}

【2】上界通配符(? extends T)

表示只能是 T 类型或 T 的子类:

// 只能处理Number及其子类(Integer, Double等)
public double sum(List<? extends Number> numbers) {double sum = 0;for (Number num : numbers) {sum += num.doubleValue();}return sum;
}

【3】下界通配符(? super T)

表示只能是 T 类型或 T 的父类:

// 可以添加Integer及其父类类型的元素
public void addNumbers(List<? super Integer> list) {list.add(1);list.add(2);list.add(new Integer(3));
}

五、类型擦除

        Java 泛型采用类型擦除(Type Erasure)实现,即在编译时检查泛型类型,然后将泛型信息擦除,生成的字节码中不包含泛型类型信息。

类型擦除规则:

  • 若指定了泛型上界,则擦除为相应的上界类型
  • 若未指定上界,则擦除为 Object 类型

类型擦除带来的限制:

  • 不能使用new T()创建泛型实例
  • 不能使用T.class获取 Class 对象
  • 不能使用泛型数组new T[]
  • 不能在静态环境中使用类的泛型参数

六、泛型的最佳实践

  1. 始终使用具体的泛型类型,避免使用原始类型(如 List 而非 List<?>)
  2. 优先使用泛型方法而非泛型类,减少泛型范围
  3. 合理选择通配符类型
    • 读取数据时使用上界通配符(? extends T)
    • 写入数据时使用下界通配符(? super T)
  4. 避免过度泛型化,不要为简单场景引入复杂的泛型结构
  5. 使用 @SuppressWarnings ("unchecked") 注解抑制必要的 unchecked 警告

七、总结

        泛型是 Java 中提高代码复用性和类型安全性的重要机制,通过参数化类型实现了通用代码与具体类型的解耦。掌握泛型的使用不仅能够写出更优雅、更安全的代码,也是理解 Java 集合框架等核心 API 的基础。


        感谢你花时间读到这里~ 如果你觉得这篇内容对你有帮助,不妨点个赞让更多人看到;如果有任何想法、疑问,或者想分享你的相关经历,欢迎在评论区留言交流,你的每一条互动对我来说都很珍贵~ 我们下次再见啦!😊😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96641.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96641.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96641.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式 Linux 启动机制全解析:从 Boot 到 Rootfs

&#x1f680; 嵌入式 Linux 启动机制全解析&#xff1a;从 Boot 到 Rootfs 在嵌入式系统中&#xff0c;Linux 的启动流程不仅是内核加载的过程&#xff0c;更是 bootloader、设备树、初始根文件系统、启动配置文件等多个组件协同工作的结果。不同的文件系统和启动方式会影响系…

Python 操作Office的PPT、Word、Excel,同时兼容WPS

文章目录概要一、环境准备1. 安装必要的Python库2. 系统要求二、核心实现原理1. 检测已安装的Office类型2. 初始化对应的应用程序三、完整代码实现四、使用示例五、WPS兼容处理详解1. 形状和文本框访问兼容处理2. PPT图片粘贴兼容处理3. 资源释放的重要性六、图片操作实现详解1…

ISP之DHCPv6-PD(前缀代理)为用户下发前缀

一、组网需求家庭用户要使用IPv6地址接入互联网。为方便用户接入&#xff0c;运营商使用DHCPv6-PD的方式给家用路由器下发IPv6地址前缀&#xff0c;用户路由器LAN侧不需要手工指定链路的IPv6地址前缀&#xff0c;家用路由器可以给用户终端自动配置IPv6地址和其它网络参数。本例…

Django全栈班v1.04 Python基础语法 20250912 上午

rm 删除命令 注意&#xff1a;删除操作是不可逆的&#xff0c;一旦删除就无法撤销&#xff0c;请谨慎使用。删除文件&#xff1a; rm file.py递归删除目录&#xff1a; rm -r demo/强制删除&#xff1a; rm -f file.py交互式删除&#xff1a; rm -i *.txt课程定位 “学习Python…

Java 21 虚拟线程高并发落地:中间件适配、场景匹配与细节优化的技术实践

作为 Java 21 的核心特性,虚拟线程(Virtual Thread)凭借 “用户态调度”“轻量级资源占用” 的优势,成为高并发场景下线程模型优化的重要方向。但在实际落地中,不少团队会陷入 “技术用了却没效果” 的困境 ——QPS 提升有限、中间件调用阻塞、CPU 使用率异常升高。 本文…

数据库在并发访问时,不同隔离级别下脏读幻读问题

数据库隔离级别并非安装后就固定&#xff0c;绝大多数主流数据库&#xff08;如MySQL、PostgreSQL、SQL Server&#xff09;都支持动态调整和运行中自定义&#xff0c;具体调整范围可分为全局、会话和语句三个层级。 全局级别调整&#xff1a;修改数据库配置文件&#xff08;如…

JVM从入门到实战:从字节码组成、类生命周期到双亲委派及打破双亲委派机制

摘要&#xff1a;本文围绕 Java 字节码与类加载机制展开&#xff0c;详解字节码文件组成、类的生命周期&#xff0c;介绍类加载器分类、双亲委派机制及打破该机制的方式&#xff0c;还阐述了线程上下文类加载器与 SPI 机制在 JDBC 驱动加载中的应用&#xff0c;帮助深入理解 Ja…

多源最短路(Floyd算法

多源最短路简介 多源最短路算法用于解决图中任意两节点间最短路径的问题&#xff0c;广泛应用于交通网络、社交关系分析、路由优化等场景。与单源最短路&#xff08;如Dijkstra&#xff09;不同&#xff0c;它一次性计算所有节点对的最短距离&#xff0c;适合需要全局路径规划的…

【攻防实战】记一次攻防实战全流程

那天我向众神祈祷&#xff0c;最后回答我的却只有挣扎十年依旧不甘的自己&#xff01;成功究竟是馈赠还是偿还。 前言 网络安全技术学习&#xff0c;承认⾃⼰的弱点不是丑事&#xff0c;只有对原理了然于⼼&#xff0c;才能突破更多的限制。 拥有快速学习能力的安全研究员&…

Anaconda配置环境变量和镜像

Anaconda配置环境变量和镜像 下载失败就是开了梯子 Anaconda 作用&#xff1a;包管理&#xff08;集中&#xff0c;有序&#xff09;和环境管理&#xff08;版本切换&#xff09;使用conda命令对虚拟环境创建、删除自带python解释器pip&#xff08;python自带的包管理工具&…

给定单词倒排

实现代码&#xff1a;public static void main(String[] args) {Scanner scanner new Scanner(System.in);// 输入的字符串String input scanner.nextLine();// 存储单词List<String> words new ArrayList<>();// 存储当前单词StringBuilder currentWord new S…

IO进程——进程引入、进程函数接口

一、引入1、进程&程序1.1 程序编译好的可执行的文件存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09;程序是静态的&#xff0c;没有任何执行的概念1.2 进程一个独立的可调度的任务执行一个程序所分配的资源的总称进程是程序执行的一次过程进程是动态的&…

周末游戏推荐:安卓端俄罗斯方块,经典与创新的结合

前段时间&#xff0c;每到周末我都会给大家推荐一些离线的经典游戏&#xff0c;原本打算将这个传统一直延续下去。然而&#xff0c;我实在找不到足够好用且无广告的游戏了。有些游戏刚开始用的时候还不错&#xff0c;但用着用着就开始频繁弹出广告&#xff0c;这让我实在不敢向…

《用 Scikit-learn 构建 SVM 分类模型:从原理到实战的全流程解析》

《用 Scikit-learn 构建 SVM 分类模型:从原理到实战的全流程解析》 一、引言:为什么选择 SVM? 在机器学习的众多算法中,支持向量机(SVM)以其强大的分类能力和良好的泛化性能,在文本分类、人脸识别、医学诊断等领域广泛应用。尤其在中小规模数据集上,SVM 往往能提供比…

一文学会CMakeLists.txt: CMake现代C++跨平台工程化实战

你能学到什么&#xff1f;朋友们好久不见&#xff0c;我是alibli&#xff0c;好久没有更新博客了。今天本人将通过构造一个实际的虚拟小项目&#xff0c;来让你彻底掌握CMake跨平台工程构建&#xff0c;学会CMakeLists.txt语法。该项目实现了一个简单的平方、立方的计算程序&am…

高并发场景下限流算法实践与性能优化指南

高并发场景下限流算法实践与性能优化指南 在大规模并发访问环境中&#xff0c;合理的限流策略能保护后端服务稳定运行&#xff0c;避免系统因瞬时高并发导致资源耗尽或崩溃。本文将从原理出发&#xff0c;深入解析几种主流限流算法&#xff0c;并结合Java和Redis给出完整可运行…

Vue3应用执行流程详解

精确化的完整执行流程 (以 Vite Vue3 SPA 为例)整个过程可以分为两部分&#xff1a;首次访问的“冷启动”和后续的Vue应用接管。第一部分&#xff1a;首次访问与页面加载客户端&#xff1a;发送请求用户打开浏览器&#xff0c;输入 URL&#xff08;如 http://localhost:5173&a…

Redis 持久化与高可用实践(RDB / AOF / Sentinel / Cluster 全解析)

这篇是我把几套生产环境踩坑与复盘整理成的一份“从 0 到 1 长期可维护”的实践文。目标是&#xff1a;明确策略、给出默认可用的配置模板、把常见坑一次讲透。 适用场景&#xff1a;新项目选型、老项目稳定性加固、从单机迁移到 HA/Cluster、应对数据安全与故障切换要求。目录…

Linux内核的PER_CPU机制

参考书《Linux内核模块开发技术指南》 1.原理 在多核CPU的情况下&#xff0c;为了提高CPU并发执行的效率&#xff0c;对于某些不是必须要在核间进行同步访问的资源&#xff0c;可以为每一个CPU创建一个副本&#xff0c;让每个CPU都访问自身的数据副本&#xff0c;而不是通过加锁…

VSCode 的百度 AI编程插件

VSCode 的百度 AI编程插件主要是 Baidu Comate&#xff08;文心快码&#xff09;&#xff0c;这是一款基于文心大模型的新一代编码辅助工具&#xff0c;旨在提升开发者的编码效率&#xff0c;让写代码变得更简单。以下是关于 Baidu Comate 的详细介绍&#xff1a; 一、功能特点…