当前位置: 首页 > news >正文

Java 基础之泛型:类型安全的保障与灵活运用

        在 Java 编程的世界里,泛型是一个至关重要且非常实用的特性。它在 Java 5 中被引入,从根本上改变了我们处理数据类型的方式,提供了更强的类型安全保障,同时也增加了代码的复用性和可读性。

一、什么是泛型

        泛型(Generics)简单来说,就是允许在定义类、接口和方法时使用类型参数。这些类型参数在使用时会被具体的类型所替代。例如,我们常见的集合类ArrayList就是一个泛型类,它的定义形式是ArrayList<E>,这里的E就是类型参数,在实际使用中,我们可以指定EStringInteger等具体类型,如ArrayList<String>

二、泛型的优势

(一)类型安全

  1. 避免类型转换错误
    • 在没有泛型之前,如果我们有一个存放Object类型的集合,当我们从集合中取出元素时,需要进行强制类型转换。例如:
ArrayList list = new ArrayList();
list.add("Hello");
String s = (String)list.get(0);
  • 但是,如果在这个集合中不小心添加了一个非String类型的元素,比如Integer,在运行时进行类型转换时就会抛出ClassCastException异常。而使用泛型,如ArrayList<String>,编译器就能在编译阶段检查出类型不匹配的问题,防止这种运行时错误的发生。
  1. 提高代码的健壮性
    • 泛型使得代码在编译时就可以发现更多的错误,从而减少了因类型不匹配导致的运行时错误。这使得我们的程序更加健壮,减少了调试的时间和成本。

(二)代码复用

  1. 泛型类和泛型方法
    • 我们可以编写泛型类和泛型方法来处理不同类型的数据。例如,我们可以编写一个泛型方法来交换两个变量的值:
public static <T> void swap(T[] array, int i, int j) {T temp = array[i];array[i] = array[j];array[j] = temp;
}

  • 这个方法可以用于交换Integer数组、String数组等不同类型数组中的元素,大大提高了代码的复用性。

(三)提高代码可读性

  1. 清晰的类型声明
    • 当我们看到ArrayList<String>时,我们可以很清楚地知道这个集合中存放的是String类型的元素。这种清晰的类型声明使得代码的意图更加明显,提高了代码的可读性,尤其是在处理复杂的数据结构和算法时。

三、泛型的主要应用场景

(一)集合框架

  1. ArrayListLinkedList
    • 这些都是泛型类,我们可以根据需要指定它们所存储的元素类型。例如:
ArrayList<Integer> intList = new ArrayList<>();
LinkedList<Double> doubleList = new LinkedList<>();
  • 这使得我们在操作集合中的元素时更加方便和安全。
  1. HashSetTreeSet
    • 这些集合类也利用了泛型。HashSet是基于哈希表实现的集合,TreeSet是基于红黑树实现的有序集合。在使用时,我们可以指定元素类型,如HashSet<String>TreeSet<Employee>(假设Employee是我们自定义的员工类)。

(二)泛型方法

  1. 实现通用算法
    • 除了上面提到的交换数组元素的泛型方法外,还有很多其他的应用场景。例如,我们可以编写一个泛型方法来查找数组中的最大值:
public static <T extends Comparable<T>> T findMax(T[] array) {T max = array[0];for (int i = 1; i < array.length; i++) {if (array[i].compareTo(max)> 0) {max = array[i];}}return max;
}
  • 这个方法适用于实现了Comparable接口的任何类型的数组,比如Integer数组、String数组等。

四、泛型相关的重要概念

(一)泛型类型参数的限定

  1. extends关键字
    • 当我们定义泛型类或泛型方法时,有时需要对类型参数进行限定。例如,在上面查找最大值的泛型方法中,我们使用了<T extends Comparable<T>>,这表示类型T必须是实现了Comparable<T>接口的类型。这样做的目的是为了在方法中能够调用compareTo方法来比较元素的大小。
  2. super关键字(较少用但很重要)
    • super关键字用于指定类型参数的下限。例如,<? super Integer>表示这个类型参数必须是Integer或者Integer的父类。这种用法在编写某些类型安全的方法时非常有用,比如Collections类中的一些方法。

(二)通配符

  1. ?通配符
    • 通配符?用于表示不确定的类型。例如,我们有一个方法用于打印集合中的元素:
public static void printList(ArrayList<?> list) {for (Object obj : list) {System.out.println(obj);}
}
  • 这里的ArrayList<?>表示这个方法可以接受任意类型的ArrayList。但是,由于类型不确定,我们在方法中不能向集合中添加除null以外的元素(因为编译器不知道具体的类型,无法保证类型安全)。
  1. 有界通配符
    • 有界通配符分为上界通配符(<? extends T>)和下界通配符(<? super T>)。上界通配符用于表示类型必须是某个类的子类或实现了某个接口的类型,下界通配符用于表示类型必须是某个类的父类。它们在方法参数和返回值的类型声明中非常有用,可以实现更加灵活和类型安全的编程。

五、泛型在编译时的处理

  1. 类型擦除
    • Java 中的泛型是通过类型擦除来实现的。这意味着在编译时,泛型类型信息会被擦除,只保留原始类型。例如,ArrayList<String>ArrayList<Integer>在编译后都变成了ArrayList(原始类型)。
    • 但是,编译器会在编译阶段插入必要的类型转换和类型检查代码,以保证运行时的类型安全。这就是为什么泛型能够在编译时发现类型不匹配问题的原因。

六、总结

泛型是 Java 中一个非常强大的特性,它在类型安全、代码复用和可读性方面都有着显著的优势。通过合理地运用泛型,我们可以编写更加健壮、高效和易于维护的 Java 代码。无论是在集合框架的使用中,还是在实现通用算法的泛型方法中,泛型都发挥着重要的作用。理解和掌握泛型的概念、应用场景和相关技术细节,对于成为一名优秀的 Java 程序员是必不可少的。

希望这篇文章能够帮助大家更好地理解 Java 中的泛型,在编程实践中能够更加熟练地运用这一强大的工具!

相关文章:

Java 基础之泛型:类型安全的保障与灵活运用

在 Java 编程的世界里&#xff0c;泛型是一个至关重要且非常实用的特性。它在 Java 5 中被引入&#xff0c;从根本上改变了我们处理数据类型的方式&#xff0c;提供了更强的类型安全保障&#xff0c;同时也增加了代码的复用性和可读性。 一、什么是泛型 泛型&#xff08;Gener…...

开发者如何使用GCC提升开发效率Opencv操作

看此篇前请先阅读 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144216351?spm=1001…...

矩阵加法        ‌‍‎‏

矩阵加法 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输入两个n行m列的矩阵A和B&#xff0c;输出它们的和AB。 输入 第一行包含两个整数n和m&#xff0c;表示矩阵的行数和列数。1 <…...

yarn : 无法加载文件 E:\node\node_global\yarn.ps1,因为在此系统上禁止运行脚本

先确保安装了yarn —— npm install -g yarn 终端输入set-ExecutionPolicy RemoteSigned 若要在本地计算机上运行您编写的未签名脚本和来自其他用户的签名脚本&#xff0c;请使用以下命令将计算机上的执行策略更改为RemoteSigned 再去使用yarn okk~...

详解C++类与对象(四)

文章目录 1.类型转换1.1 前言1.2 类型转换的性质 2.static成员2.1 前言2.2 static的基本概念 3.友元4.内部类5.匿名对象 1.类型转换 1.1 前言 在C中&#xff0c;由于程序员可以自己显示定义一个新的类。这样就会出现一个问题&#xff1a;程序员自己显示定义的类类型与编译器中…...

Pandas处理和分析嵌套JSON数据:从字符串到结构化DataFrame

在数据分析领域&#xff0c;我们经常遇到需要从非结构化数据中提取有用信息的场景。特别是当数据以JSON字符串的形式出现时&#xff0c;如何有效地将其转换为结构化的表格形式&#xff0c;以便进行进一步的分析和处理&#xff0c;成为了一个常见的挑战。本文将通过一个具体的例…...

【强化学习入门笔记】1.5 贝尔曼最优公式

本系列为学习赵世钰老师的《强化学习的数学原理》所作的学习笔记. 课程视频网址&#xff1a;https://space.bilibili.com/2044042934 1.5.1 定义 1.5.1.1 Contraction mapping theorem (收缩映射定理) fixed point(不动点) 如果 x ∗ x^* x∗满足下式, x ∗ x^* x∗称之为…...

编码问题技术探讨:IDE全局GBK与项目UTF-8引发的中文乱码

在软件开发过程中&#xff0c;编码问题一直是开发者们需要面对和解决的难题之一。尤其是在使用IDE&#xff08;集成开发环境&#xff09;时&#xff0c;如果全局编码设置与项目编码设置不一致&#xff0c;往往会导致中文乱码的问题。本文将深入探讨这一问题的背景、示例以及解决…...

SpringBoot两天

SpringBoot讲义 什么是SpringBoot&#xff1f; Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xf…...

自动化立体仓库项目任务调度系统中任务流程可视化实现

在运维自动化平台中,任务系统无疑是最核心的组成部分之一。它承担着所有打包编译、项目上线、日常维护等运维任务的执行。通过任务系统,我们能够灵活地构建满足不同需求的自定义任务流。早期的任务流后端采用了类似列表的存储结构,根据任务流内子任务的排序依次执行,尽管通…...

计算机毕业设计hadoop+spark民宿推荐系统 民宿数据分析可视化大屏 民宿爬虫 民宿大数据 知识图谱 机器学习 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

Java中OGNL表达式语言的使用

文章目录 OGNL 介绍OGNL 使用场景- ognl- 主要功能- 注意事项- Ognl类的主要方法- 设置值- 获取值- 使用示例 - MybatisJava原生表达式的使用 - Fastjson- JSONPath类的主要方法- 主要功能- JSONPath的优势- 使用示例 Spring不选择OGNL的原因 OGNL 介绍 OGNL&#xff08;Objec…...

[HCTF 2018]WarmUp-滑稽

启动场景打开链接&#xff0c;出现一下图片 F12查看代码出现一个注释&#xff0c;应该在这个文件中&#xff0c; 进入到该页面&#xff0c;出现一段代码 <?phphighlight_file(__FILE__);class emmm{public static function checkFile(&$page){$whitelist ["sourc…...

JAVAWeb——maven、SpringBoot、HTTP、Tomcat

目录 1.maven a.概述 b.作用 c.仓库 b.坐标 c.依赖管理 2.SpringBoot 3.HTTP a.概述 b.请求协议 c.响应协议 d.协议解析 4.Tomcat a.Web服务器 b.Tomcat c.SpringBoot与Tomcat关系 1.maven a.概述 Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理…...

【C++】—— set 与 multiset

【C】—— map 与 set 1 序列式容器和关联式容器2 set 系列的使用2.1 set 和 multiset 参考文档2.2 set 类的介绍2.3 set 的迭代器和构造2.4 set的增删查2.4.1 insert2.4.2 find 与 erase2.4.3 count 2.5 lower_bound 与 upper_bound2.6 multiset 与 set 的差异2.6.1 不再去重2…...

蓝桥杯-扫雷

这题不难&#xff0c;就是麻烦一点&#xff0c;这里暴力求解了直接 题目链接&#xff1a; 扫雷 AC代码&#xff1a; import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner scan ne…...

黑马JavaWeb-day06、07、08(SQL部分) _

文章目录 MYSQL概述数据模型SQL简介SQL分类 DDL数据库操作表操作 DML增&#xff08;INSERT&#xff09;改&#xff08;UPDATE&#xff09;删&#xff08;DELETE&#xff09; DQL基本查询条件查询&#xff08;where&#xff09;分组查询&#xff08;group by&#xff09;排序查询…...

三十五:Wireshark的捕获过滤器

Wireshark 是一个广泛使用的网络协议分析工具&#xff0c;主要用于捕获和分析网络流量。它支持丰富的协议分析&#xff0c;并提供了多种过滤方式&#xff0c;以便用户在大量数据中精确地找到自己关注的内容。在Wireshark中&#xff0c;过滤器可以分为两类&#xff1a;捕获过滤器…...

第9章 大模型的有害性(上)

9.1 引言 本章将探讨大型语言模型&#xff08;LLMs&#xff09;可能带来的有害性&#xff0c;重点讨论以下几个方面&#xff1a; 性能差异社会偏见和刻板印象 在后续内容中&#xff0c;还会涉及其他层面的危害&#xff0c;如有害信息、虚假信息、隐私和安全风险、版权问题、…...

遗传算法与深度学习实战(26)——编码卷积神经网络架构

遗传算法与深度学习实战&#xff08;26&#xff09;——编码卷积神经网络架构 0. 前言1. EvoCNN 原理1.1 工作原理1.2 基因编码 2. 编码卷积神经网络架构小结系列链接 0. 前言 我们已经学习了如何构建卷积神经网络 (Convolutional Neural Network, CNN)&#xff0c;在本节中&a…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

STM32+rt-thread判断是否联网

一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...