Java 中的泛型讲解与使用(超全详解)

Java 中的泛型(超全详解)

在 Java 编程中,泛型是一种强大的特性,它允许我们编写可以处理多种数据类型的代码,从而提高代码的复用性和安全性。本文将对 Java 中的泛型进行超全详解,包括泛型的基本概念、基本用法、通配符、泛型方法、类型擦除以及实际应用示例,帮助你全面掌握泛型的使用。

一、泛型的基本概念

1. 什么是泛型?

泛型是 Java SE 5 引入的一种特性,它允许我们在编译时指定类型参数,从而避免在运行时进行类型转换和类型检查。泛型的本质是在编译时进行类型检查,确保类型安全。

2. 为什么使用泛型?

在没有泛型之前,我们通常使用 Object 类型来表示集合中的元素,然后在使用时进行类型转换。这种方式容易导致类型转换异常和代码不安全。泛型的引入解决了这些问题,它可以在编译时进行类型检查,避免类型转换异常,提高代码的安全性和可读性。

二、泛型的基本用法

1. 泛型类

泛型类是在类定义时使用类型参数的类。例如,ArrayList 是一个泛型类,它可以存储任意类型的对象。

示例代码
import java.util.ArrayList;public class GenericClassExample {public static void main(String[] args) {// 创建一个泛型类的实例ArrayList<String> list = new ArrayList<>();// 添加元素list.add("Hello");list.add("World");// 遍历元素for (String s : list) {System.out.println(s);}}
}

2. 泛型接口

泛型接口是在接口定义时使用类型参数的接口。例如,Comparable 是一个泛型接口,它可以用于定义对象的排序规则。

示例代码
import java.util.ArrayList;
import java.util.Collections;public class GenericInterfaceExample {public static void main(String[] args) {// 创建一个泛型接口的实现类ArrayList<String> list = new ArrayList<>();list.add("Banana");list.add("Apple");list.add("Cherry");// 排序Collections.sort(list);// 遍历元素for (String s : list) {System.out.println(s);}}
}

3. 泛型方法

泛型方法是在方法定义时使用类型参数的方法。例如,Arrays.asList 是一个泛型方法,它可以将数组转换为列表。

示例代码
import java.util.Arrays;
import java.util.List;public class GenericMethodExample {public static void main(String[] args) {// 创建一个数组String[] array = {"Hello", "World"};// 使用泛型方法将数组转换为列表List<String> list = Arrays.asList(array);// 遍历元素for (String s : list) {System.out.println(s);}}
}

三、通配符

在使用泛型时,我们有时需要处理未知类型的集合。这时可以使用通配符 ? 来表示未知类型。

1. 无界通配符

无界通配符 ? 表示未知类型,可以用于读取集合中的元素,但不能用于添加元素。

示例代码
import java.util.ArrayList;public class WildcardExample {public static void main(String[] args) {// 创建一个泛型类的实例ArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("World");// 使用无界通配符读取元素printList(list);}public static void printList(List<?> list) {for (Object s : list) {System.out.println(s);}}
}

2. 有界通配符

有界通配符 ? extends T 表示未知类型是 TT 的子类,? super T 表示未知类型是 TT 的父类。

示例代码
import java.util.ArrayList;public class BoundedWildcardExample {public static void main(String[] args) {// 创建一个泛型类的实例ArrayList<Animal> list = new ArrayList<>();list.add(new Dog());list.add(new Cat());// 使用有界通配符读取元素printList(list);}public static void printList(List<? extends Animal> list) {for (Animal animal : list) {System.out.println(animal);}}
}class Animal {public String toString() {return "Animal";}
}class Dog extends Animal {public String toString() {return "Dog";}
}class Cat extends Animal {public String toString() {return "Cat";}
}

四、类型擦除

类型擦除是泛型实现的一个重要概念。在编译时,泛型类型信息会被擦除,只保留原始类型。这意味着在运行时,泛型类型信息是不可用的。

1. 类型擦除的影响

类型擦除会导致一些问题,例如无法在运行时获取泛型类型信息,无法使用反射获取泛型类型参数等。

2. 解决方法

为了解决类型擦除的问题,可以使用 Class 类来获取类型信息,或者使用 Type 接口来获取泛型类型参数。

示例代码
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class TypeErasureExample {public static void main(String[] args) {// 获取泛型类型参数Type type = new ArrayList<String>() {}.getClass().getGenericSuperclass();ParameterizedType parameterizedType = (ParameterizedType) type;Type[] typeArguments = parameterizedType.getActualTypeArguments();System.out.println("泛型类型参数: " + typeArguments[0]);}
}

五、实际应用示例

1. 泛型在集合框架中的应用

泛型在 Java 的集合框架中得到了广泛应用,例如 ArrayListHashMap 等。

示例代码
import java.util.ArrayList;
import java.util.HashMap;public class GenericInCollectionExample {public static void main(String[] args) {// 使用泛型的 ArrayListArrayList<String> list = new ArrayList<>();list.add("Hello");list.add("World");// 使用泛型的 HashMapHashMap<String, Integer> map = new HashMap<>();map.put("One", 1);map.put("Two", 2);// 遍历集合for (String s : list) {System.out.println(s);}for (String key : map.keySet()) {System.out.println(key + ": " + map.get(key));}}
}

2. 泛型在自定义类中的应用

我们可以在自定义类中使用泛型,从而提高代码的复用性和安全性。(点击链接跳转见详情)
java泛型在自定义类中的应用-CSDN博客

六、总结

通过本文的介绍,我们全面了解了 Java 中泛型的基本概念、基本用法、通配符、泛型方法、类型擦除以及实际应用示例。泛型是 Java 编程中一个重要的特性,它可以在编译时进行类型检查,提高代码的安全性和可读性。希望本文的内容能够帮助你更好地理解和使用泛型,从而提高你的编程水平。

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

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

相关文章

【odoo18-文件管理】在uniapp上访问odoo系统上的图片

在uniapp上访问odoo系统上的图片 1、以url的形式访问 a&#xff1a;以odoo本身的域名&#xff0c;比如http://127.0.0.1:8069/web/image/product.template/3/image_128?unique1740380422000&#xff0c;这种方式需要解决跨域的问题。 b&#xff1a;以文件服务器的形式&…

DeepSeek掘金——基于DeepSeek-R1构建文档问答机器人

DeepSeek掘金——基于DeepSeek-R1构建文档问答机器人 在这个项目中,我们将结合本地 AI 的隐私与 Deepseek R1 的智能,创建一个完全本地化、推理驱动的问答机器人。 在人工智能 (AI) 日益融入我们日常生活的时代,一个问题仍然处于最前沿:隐私。尽管基于云的 AI 系统功能强大…

计算机毕业设计Hadoop+Spark+DeepSeek-R1大模型民宿推荐系统 hive民宿可视化 民宿爬虫 大数据毕业设计(源码+文档+PPT+讲解)

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

将maya模型物体材质转化为面材质

将maya模型物体材质转化为面材质&#xff0c;以在导出abc时继承材质信息&#xff1b; 运行一下python代码&#xff1a; import maya.cmds as cmds objListcmds.ls(slTrue) for obj in objList:shapeNodeNamecmds.listRelatives(obj, shapesTrue)sgNodesListcmds.listConnecti…

数据库面试题(基础常考!!!)

在数据库领域&#xff0c;无论是日常开发还是面试场景&#xff0c;都有一些高频且重要的问题需要我们深入理解和掌握。本文将对这些常见面试题进行详细阐述&#xff0c;帮助大家更好地应对面试和实际工作中的挑战。 面试题一&#xff1a;三范式详解 什么是三范式 三范式是关…

论文笔记(七十二)Reward Centering(三)

Reward Centering&#xff08;三&#xff09; 文章概括摘要3 基于值的奖励中心化4 案例研究&#xff1a; 以奖励为中心的 Q-learning5 讨论、局限性与未来工作致谢 文章概括 引用&#xff1a; article{naik2024reward,title{Reward Centering},author{Naik, Abhishek and Wan…

鸿蒙开发深入浅出01(基本环境搭建、页面模板与TabBar)

鸿蒙开发深入浅出01&#xff08;基本环境搭建、页面模板与TabBar&#xff09; 1、效果展示2、下载 DevEco Studio3、创建项目4、新建页面模板5、更改应用信息6、新建以下页面7、Index.ets8、真机运行9、图片资源文件 1、效果展示 2、下载 DevEco Studio 访问官网根据自己的版本…

蓝桥杯第十六届嵌入式模拟编程题解析

由硬件框图可以知道我们要配置LED 和按键 LED 先配置LED的八个引脚为GPIO_OutPut&#xff0c;锁存器PD2也是&#xff0c;然后都设置为起始高电平&#xff0c;生成代码时还要去解决引脚冲突问题 按键 按键配置&#xff0c;由原理图按键所对引脚要GPIO_Input 生成代码&#xf…

二叉树的遍历知识点及习题

一、知识点 1二叉树的遍历理解为按照预先定好的搜索路径访问树里的每个节点&#xff0c;且每个节点仅访问一次 2假设根节点为N&#xff0c;左子树为L&#xff0c;右子树为R&#xff0c;常见的三种遍历方法分别是先&#xff08;前&#xff09;序遍历NLR 根左右&#xff0c;中序…

“conda”不是内部或外部命令,也不是可运行的程序或批处理文件

有的时候&#xff0c;我们发现在cmd黑框中输入conda时&#xff0c;cmd会显示“conda”不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件&#xff0c;那这时候该怎么解决呢&#xff1f; Step01&#xff1a;我们找到Anconda的安装目录。然后找到里面的bin文件夹&am…

特辣的海藻!3

基础知识点 判断一个数是否是2的幂次 方法一&#xff1a;位运算 所有2的幂次数的二进制表示中有且仅有一个1&#xff0c;进行位运算 n&(n-1) 后结果为0 检查正数&#xff1a;n > 0&#xff08;负数和0不是2的幂次&#xff09;位运算&#xff1a; n & ( n -1) 会…

苍穹外卖中的模块总结

本文总结苍穹外卖项目中可复用的通用设计 sky-common constant存放常量类&#xff0c;包括消息常量&#xff0c;状态常量 context是上下文对象&#xff0c;封装了threadlocal package com.sky.context;public class BaseContext {public static ThreadLocal<Long> thre…

Threejs教程一【三要素】

场景 场景是一个容器&#xff0c;用于容纳所有的物体、光源、相机等元素。 // 创建场景 const scene new THREE.Scene(); //修改背景颜色&#xff0c;颜色支持十六进制、rgb、hsl、贴图等 scene.background new THREE.Color(0x000000);相机 相机决定了渲染的结果&#xff…

Deepseek和Grok 3对比:写一段冒泡排序

1、这是访问Grok 3得到的结果 2、grok3输出的完整代码&#xff1a; def bubble_sort(arr):n len(arr) # 获取数组长度# 外层循环控制排序轮数for i in range(n):# 内层循环比较相邻元素&#xff0c;j的范围逐渐减少for j in range(0, n - i - 1):# 如果当前元素大于下一个元…

TCP/UDP调试工具推荐:Socket通信图解教程

TCP/UDP调试工具推荐&#xff1a;Socket通信图解教程 一、引言二、串口调试流程三、下载链接 SocketTool 调试助手是一款旨在协助程序员和网络管理员进行TCP和UDP协议调试的网络通信工具。TCP作为一种面向连接、可靠的协议&#xff0c;具有诸如连接管理、数据分片与重组、流量和…

Open WebUI 是什么

Open WebUI 是什么 Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台,旨在完全离线运行。它支持各种 LLM 运行器,如 Ollama 和 OpenAI 兼容的 API,并内置了 RAG 推理引擎,使其成为强大的 AI 部署解决方案。 https://github.com/open-webui/open-webui 🚀 …

登录-05.JWT令牌-介绍

一.JWT令牌 JWT令牌是一种简洁的、自包含的格式&#xff0c;用于在通讯双方之间以json数据格式安全的传输数据。说白了&#xff0c;JWT令牌就是将json格式的数据进行封装&#xff0c;从而实现安全传输。 所谓简洁&#xff0c;就是指JWT令牌就是一个简单的字符串。 所谓自包含…

短剧小程序系统源码

短剧小程序系统源码 今天我要向大家介绍的是最新作品——短剧小程序系统源码。这不仅仅是一款简单的播放工具&#xff0c;它背后蕴含的强大功能能够帮助你的短剧业务实现质的飞跃&#xff01; 为什么说这款源码很厉害&#xff1f; 首先&#xff0c;在当今竞争激烈的市场环境…

【够用就好006】-PC桌面管理ECS服务器的实操步骤

背景介绍解决思路拓展知识 背景介绍 #够用就好#知其然知其所以然#aigc创意人左边 我计划搭建个人网站&#xff0c;计划格式化我的ECS服务器&#xff0c;但是里面有我之前的实践项目&#xff0c;我舍不得删除&#xff0c;我想要保存到本地。 通常我都是在vscode中用remotes ssh…

Ubuntu非conda环境python3.8下安装labelme

很久没用过labelme了&#xff0c;造实验数据需要在一个没有conda的Ubuntu20.04安装了python3.8.10的环境下安装labelme&#xff0c;先是直接执行 pip install labelme 执行了多次每次都是卡死&#xff0c;后来先执行pip install pyqt发现也是卡死在同样的地方&#xff0c;发现…