Java基础:泛型

什么是泛型?

简单来说,Java泛型是JDK 5引入的一种特性,它允许你在定义类、接口和方法时使用类型参数(Type Parameters)。这些类型参数可以在编译时被具体的类型(如 String, Integer, MyCustomClass 等)所替代。泛型的核心目的是在编译时提供类型安全,并**消除类型转换(Cast)**的需要。

为什么需要泛型?(主要解决的问题)

在泛型出现之前(JDK 5之前),集合类(如 ArrayList, Vector 等)是非类型安全的。它们只能存储 Object 类型的对象,这意味着你可以向一个 ArrayList 中添加任何类型的对象。

// JDK 5 之前的写法
List list = new ArrayList(); // 默认是 List<Object>
list.add("Hello"); // 可以添加 String
list.add(123);     // 也可以添加 Integer
list.add(new Date());// 还可以添加 Date
// 遍历时需要强制类型转换,且容易出错
for (int i = 0; i < list.size(); i++) {String str = (String) list.get(i); // 在这里会抛出 ClassCastException,因为第2、3个元素不是 StringSystem.out.println(str);
}

这种方式的缺点:

  1. 类型不安全:编译器无法在编译时检查你添加到集合中的对象类型是否符合预期,只有在运行时通过 get() 方法取出元素并进行强制类型转换时,如果类型不匹配才会抛出 ClassCastException
  2. 需要频繁的类型转换:每次从集合中取出元素时,都需要手动进行类型转换,代码冗余且容易出错。
    泛型就是为了解决这两个问题而设计的。
    泛型如何工作?
  3. 类型参数化:在定义类、接口或方法时,使用类型参数(通常用大写字母表示,如 T, E, K, V 等)。
    // 定义一个泛型类
    public class Box<T> {private T content;public void setContent(T content) {this.content = content;}public T getContent() {return content;}
    }
    // 定义一个泛型方法
    public static <E> void printArray(E[] inputArray) {for (E element : inputArray) {System.out.printf("%s ", element);}System.out.println();
    }
    
  4. 实例化时指定具体类型:在使用泛型类或调用泛型方法时,指定类型参数的具体类型。
    // 创建一个只能存储 String 的 Box 实例
    Box<String> stringBox = new Box<>();
    stringBox.setContent("Hello Generics"); // 可以
    // stringBox.setContent(123); // 编译错误!不能放入 Integer
    String content = stringBox.getContent(); // 不需要强制转换,直接得到 String
    // 创建一个只能存储 Integer 的 Box 实例
    Box<Integer> integerBox = new Box<>();
    integerBox.setContent(123); // 可以
    // integerBox.setContent("Not an Integer"); // 编译错误!
    Integer intContent = integerBox.getContent(); // 不需要强制转换,直接得到 Integer
    // 调用泛型方法
    Integer[] intArray = {1, 2, 3};
    String[] strArray = {"A", "B", "C"};
    printArray(intArray); // 编译器会推断出 E 是 Integer
    printArray(strArray); // 编译器会推断出 E 是 String
    

泛型的优势:

  1. 类型安全:编译器会在编译时检查类型,确保你只能向集合或对象中添加指定类型的元素,避免了运行时 ClassCastException 的风险。
  2. 消除强制类型转换:从集合或对象中取出元素时,可以直接得到指定类型的对象,无需手动进行类型转换,代码更简洁、更安全。
  3. 代码复用:可以编写与特定类型无关的代码(如通用的集合类),通过泛型参数来适应不同的数据类型,提高了代码的复用性。
  4. 更好的可读性:代码清晰地表达了意图,即某个集合或对象预期存储或操作的是哪种类型的元素。

泛型的实现细节(类型擦除 Type Erasure)

虽然泛型提供了编译时的类型检查,但在Java的底层实现中,泛型信息在编译后会被擦除。也就是说,泛型类型 List<String>List<Integer> 在运行时实际上是同一个类型 List(或者更准确地说,是原始类型 List,因为它没有泛型参数)。编译器会在编译时插入必要的类型检查和类型转换代码。
例如,Box<String> 在编译后,其字段 content 的类型仍然是 Object,但编译器会在 setContent 方法中插入检查传入参数是否为 String 的代码,并在 getContent 方法中插入将 Object 转换为 String 的代码。
类型擦除是为了保持向后兼容性(旧代码不能使用泛型),但也带来了一些限制,比如不能创建泛型类型的数组,不能实例化泛型类型本身(new T() 是不允许的)等。

总结:

Java泛型是一种强大的工具,它通过在编译时引入类型参数,极大地增强了代码的类型安全性,减少了运行时错误,并简化了代码(通过消除不必要的类型转换)。虽然其底层实现依赖于类型擦除,但这并不影响它在提高代码质量、可读性和复用性方面的巨大价值。在现代Java开发中,泛型(尤其是在集合框架中)是不可或缺的一部分。

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

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

相关文章

RMSNorm实现

当前Qwen、Llama等系列RMSNorm实现源码均一致。具体现实如下&#xff1a; class RMSNorm(nn.Module):def __init__(self, hidden_size, eps1e-6):super().__init__()self.weight nn.Parameter(torch.ones(hidden_size))self.variance_epsilon epsdef forward(self, hidden_s…

智能Agent场景实战指南 Day 11:财务分析Agent系统开发

【智能Agent场景实战指南 Day 11】财务分析Agent系统开发 文章标签 AI Agent,财务分析,LLM应用,智能财务,Python开发 文章简述 本文是"智能Agent场景实战指南"系列第11篇&#xff0c;聚焦财务分析Agent系统的开发。文章深入解析如何构建一个能够自动处理财务报表…

人工智能安全基础复习用:可解释性

一、可解释性的核心作用1. 错误检测与模型改进发现模型的异常行为&#xff08;如过拟合、偏见&#xff09;&#xff0c;优化性能。例&#xff1a;医疗模型中&#xff0c;可解释性帮助识别误诊原因。2. 安全与可信性关键领域&#xff08;医疗、军事&#xff09;需透明决策&#…

Qt:QCustomPlot类介绍

QCustomPlot的核心类就是QCustomPlot类。这个类继承自QWidget&#xff0c;因此可以像其他QWidget一样使用&#xff0c;比如放入布局中。QCustomPlot类基本结构一个QCustomPlot对象可以包含多个图层&#xff08;通过QCPLayer表示&#xff09;&#xff0c;通常使用默认图层。它包…

Visual Studio 2022 上使用ffmpeg

目录 1. 添加包含目录 2. 添加库目录 3. 添加依赖项 4. 添加动态库目录 5. 测试 在解决方案中右击项目名称&#xff0c;弹出的窗口中选择 "属性"。 1. 添加包含目录 "C/C" -> "常规" -> "附加包含目录"中添加 ffmpeg中的…

Elasticsearch 线程池

Elasticsearch 线程池「每个线程池到底采用哪种实现策略」&#xff1a;Elasticsearch 线程池&#xff08;ThreadPool&#xff09;中 **所有内置线程池名称的常量定义**。 每个字符串常量对应一个 **线程池的名字&#xff08;name&#xff09;**&#xff0c;也就是你在 Thread…

深入理解 Next.js API 路由:构建全栈应用的终极指南

Next.js 是一个强大的 React 框架&#xff0c;不仅支持服务端渲染&#xff08;SSR&#xff09;和静态站点生成&#xff08;SSG&#xff09;&#xff0c;还提供了内置的 API 路由功能&#xff0c;使开发者能够轻松构建全栈应用。传统的全栈开发通常需要单独搭建后端服务&#xf…

【6.1.2 漫画分布式事务技术选型】

漫画分布式事务技术选型 &#x1f3af; 学习目标&#xff1a;掌握架构师核心技能——分布式事务技术选型与一致性解决方案&#xff0c;构建高可靠的分布式系统 &#x1f3ad; 第一章&#xff1a;分布式事务模式对比 &#x1f914; 2PC vs 3PC vs TCC vs Saga 想象分布式事务就…

液冷智算数据中心崛起,AI算力联动PC Farm与云智算开拓新蓝海(二)

从算法革新到基础设施升级&#xff0c;从行业渗透到地域布局&#xff0c;人工智能算力正以 “规模扩张 效率提升”双轮驱动中国数字经济转型。中国智能算力规模将在 2025 年突破 1000 EFLOPS&#xff0c;2028 年达到 2781.9 EFLOPS&#xff0c;五年复合增长率 46.2%&#xff0…

《QtPy:Python与Qt的完美桥梁》

QtPy 是什么 在 Python 的广袤编程宇宙中&#xff0c;当涉及到图形用户界面&#xff08;GUI&#xff09;开发&#xff0c;Qt 框架宛如一颗璀璨的明星&#xff0c;散发着独特的魅力。而 QtPy&#xff0c;作为 Python 与 Qt 生态系统交互中的关键角色&#xff0c;更是为开发者们开…

ubuntu环境下调试 RT-Thread

调试 RT-Thread 下载源码 github 搜索 RT-Thread 下载源码 安装 python scons 环境 你已经安装了 kconfiglib&#xff0c;但 scons --menuconfig 仍然提示找不到它。这种情况通常是由于 Python 环境不一致 导致的&#xff1a;你在一个 Python 环境中安装了 kconfiglib&#xff…

【数据结构初阶】--顺序表(二)

&#x1f525;个人主页&#xff1a;草莓熊Lotso &#x1f3ac;作者简介&#xff1a;C研发方向学习者 &#x1f4d6;个人专栏&#xff1a; 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言&#xff1a;生活是默默的坚持&#xff0c;毅力是永久的…

Java中的方法传参机制

1. 概述Java中的方法传参机制分为两种&#xff1a;值传递&#xff08;Pass by Value&#xff09; 和 引用传递&#xff08;Pass by Reference&#xff09;。然而&#xff0c;Java中所有的参数传递都是值传递&#xff0c;只不过对于对象来说&#xff0c;传递的是对象的引用地址的…

C++——this关键字和new关键字

一、this 关键字1. 什么是 this&#xff1f;this 是 C 中的一个隐式指针&#xff0c;它指向当前对象&#xff08;即调用成员函数的对象&#xff09;&#xff0c;在成员函数内部使用&#xff0c;用于引用调用该函数的对象。每个类的非静态成员函数内部都可以使用 this。使用 thi…

Python中类静态方法:@classmethod/@staticmethod详解和实战示例

在 Python 中&#xff0c;类方法 (classmethod) 和静态方法 (staticmethod) 是类作用域下的两种特殊方法。它们使用装饰器定义&#xff0c;并且与实例方法 (def func(self)) 的行为有所不同。1. 三种方法的对比概览方法类型是否访问实例 (self)是否访问类 (cls)典型用途实例方法…

FastGPT革命:下一代语言模型的极速进化

本文深度解析FastGPT核心技术架构&#xff0c;涵盖分布式推理、量化压缩、硬件加速等前沿方案&#xff0c;包含完整落地实践指南&#xff0c;助你掌握大模型高效部署的终极武器。引言&#xff1a;当大模型遭遇速度瓶颈2023年&#xff0c;ChatGPT引爆全球AI热潮&#xff0c;但企…

Geant4 安装---Ubuntu

安装工具 C/C工具包 sudo apt install build-essentialCmake sudo apt install -y cmakeccmake sudo apt install -y cmake-curses-gui安装Qt可视化工具(不需要可视化可以不安装) sudo apt-get install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qtcreator 安装Ope…

Spring Boot中请求参数读取方式

目录 一、前言 二、六种参数读取方式 1.RequestParam 2.PathVariable 3.RequestBody 4.RequestHeader 5.CookieValue 6.MatrixVariable 三、对比和搭配 1.适用方法类型及建议使用场景 2.建议使用的请求路径注解 3. 多种参数同时使用 4.同一请求不同方案&#xff1f…

2025华为OD机试真题最新题库 (B+C+D+E+2025A+2025B卷) + 在线OJ在线刷题使用(C++、Java、Python C语言 JS合集)(正在更新2025B卷,目前已收录710道)

2025年&#xff0c;已经开始使用AB卷题库&#xff0c;题目和往期一样&#xff0c;旧题加新题的组合&#xff0c;有题目第一时间更新&#xff0c;大家可以跟着继续学习&#xff0c;目前使用复用题较多&#xff0c;可在OJ上直接找到对应的AB卷学习&#xff0c;可以放心学习&#…

分析新旧因子相关性

计算一组新因子、并分析它们与已有因子间的相关性1. 导入库和初始化环境功能代码解析数据加载2. 定义新因子计算函数功能代码解析因子 1&#xff1a;波动率过滤器&#xff08;filter_001_1&#xff09;因子 2&#xff1a;ATR 过滤器&#xff08;filter_001_2&#xff09;因子 3…