[Java] 泛型
目录
1、初识泛型
1.1、泛型类的使用
1.2、泛型如何编译的
2、泛型的上界
3、通配符
4、通配符上界
5、通配符下界
1、初识泛型
泛型:就是将类型进行了传递。从代码上讲,就是对类型实现了参数化。
泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译器去做检查
语法:
class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}class 泛型类名称<类型形参列表> extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}
例:创建一个泛型数组
class MyArray <T> {//public T[] array = new T[10]; // 1//public T[] array = (T[]) new Object[10];public Object[] array = new Object[10];// 不考虑pos非法情况,默认合法public void setValue(int pos,T val) {array[pos] = val;}public T getValue(int pos) {return (T)array[pos];//把返回的类型 强转为指定类型}public Object[] getArray() {return array;}
}
public class Test {public static void main(String[] args) {public static void main(String[] args) {MyArray<Integer> myArray = new MyArray<>();//2myArray.setValue(0,10);myArray.setValue(1,12);int ret = myArray.getValue(1);//3System.out.println(ret);myArray.setValue(2,"abc");//4MyArray<String> myArray2 = new MyArray<>();myArray2.setValue(0,"abcd");myArray2.setValue(1,"efg");String ret = myArray2.getValue(1);System.out.println(ret);}
}
代码解释:
1. 类名后的<T>代表占位符,表示当前类是一个泛型类
类型形参一般使用一个大写字母表示,常用的名称有:
- E 表示 Element
- K 表示 Key V 表示 Value
- N 表示 Number
- T 表示 Type
- S, U, V 等等 - 第二、第三、第四个类型
2. 注释1处,Java中不允许new一个泛型类型数组
- 意味着 T[] ts = new T[5]; 是不对的
- T[] array = (T[])new Object[10]; 这个方式也不太好
- 推荐这种方式 Object[] array = new Object[10];
3. 注释2处,类型后加入<Integer>指定当前类型
4. 注释3处,不需要进行强制类型转换
5. 注释4处,代码编译报错,此时因为在注释2处指定类当前的类型,此时在注释4处,编译器会在存放元素的时 候帮助我们进行类型检查。
1.1、泛型类的使用
语法:
泛型类<类型实参>变量名;// 定义一个泛型类引用
new泛型类<类型实参>(构造方法实参);// 实例化一个泛型类对象
示例:
MyArray<Integer> list = new MyArray<Integer>();
注意:泛型只能接受类,所有的基本数据类型必须使用包装类!
类型推导:
当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写
MyArray list = new MyArray<>(); // 可以推导出实例化需要的类型实参为 Integer
1.2、泛型如何编译的
泛型是编译时期存在的,当程序运行起来到JVM之后,就没有泛型的概念了,编译器生成的字节码在运行期间并不包含泛型的类型信息。
泛型在编译的时候如何编译的呢?
答:在编译的过程当中,将所有的T替换为Object这种机制,我们称为:擦除机制
注:Java的泛型机制是在编译时期实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息
总结:
- 泛型是将数据类型参数化,进行传递
- 使用<T>表示当前类是一个泛型类
- 泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换
2、泛型的上界
在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束
语法:
class 泛型类名称 {
...
}
示例:
//T 只接受 Number或Number的子类
class TestGeneric<T extends Number> {
}
//T 一定是 Number或者Number的子类
class TestGeneric<T extends Number> {}
public class Test2 {public static void main1(String[] args) {// Integer、Double等都是Number的子类TestGeneric<Number> testGeneric1 = new TestGeneric<>();TestGeneric<Integer> testGeneric2 = new TestGeneric<>();TestGeneric<Double> testGeneric3 = new TestGeneric<>();//TestGeneric<String> testGeneric4 = new TestGeneric<>(); // 编译错误}
}
1. 写一个泛型类 求一个数组中的最大值
发现报错了,因为 T 一定是引用数据类型,不能直接通过大于号小于号进行比较;T 最终被擦除为了Object 类型,而Object 类型没有实现Comparable接口,也不能通过compareTo进行比较。总结出 T 类型一定要是可以比较的
^
问题:怎么能够约束 这个T 一定是可以比较大小的?
答:T extends Comparable<T>,此时 T 一定是实现了 Comparable接口的
2. 写一个泛型方法
发现在调用的过程中没有指定参数类型。此时是通过类型推导来确定 T 的类型的
类型推导:根据实参传值 来推导 此时的类型
^
不使用类型推导的写法:
3. 静态泛型方法
不使用类型推导:
3、通配符
? 用于在泛型的使用,即为通配符
通配符解决什么问题?
上述程序会带来问题,如果现在泛型的类型设置的不是String,而是Integer
需要的解决方案:可以接收所有的泛型类型,但是又不能够让用户随意修改。这种情况就需要使用通配符 "?" 来处理
4、通配符上界
语法:
<? extends 上界>
<? extends Number>//可以传入的实参类型是Number或者Number的子类
示例:
此时无法在fun函数中对temp进行添加元素,因为temp接收的是Fruit和他的子类,此时存储的元素应该是哪个子 类无法确定。所以添加会报错!但是可以获取元素
通配符的上界,不能进行写入数据,只能进行读取数据。
5、通配符下界
语法:
<? super 下界>
<? super Integer> // 代表可以传入的实参的类型是Integer或者Integer的父类类型
示例:
通配符的下界,不能进行读取数据,只能写入数据
相关文章:
[Java] 泛型
目录 1、初识泛型 1.1、泛型类的使用 1.2、泛型如何编译的 2、泛型的上界 3、通配符 4、通配符上界 5、通配符下界 1、初识泛型 泛型:就是将类型进行了传递。从代码上讲,就是对类型实现了参数化。 泛型的主要目的:就是指定当前的容器…...
Vue3 项目中零成本接入 AI 能力(以图搜图、知识问答、文本匹配)...
以下是在 Vue3 项目中零成本接入 AI 能力(以图搜图、知识问答、文本匹配)的完整解决方案,结合免费 API 和开源工具实现,无需服务器或付费服务: 一、以图搜图(基于 Hugging Face CLIP 模型) 核心思路 通过 Hugging Face Inference API 调用 CLIP 模型,将图片转换为向…...
Spark–steaming
实验项目: 找出所有有效数据,要求电话号码为11位,但只要列中没有空值就算有效数据。 按地址分类,输出条数最多的前20个地址及其数据。 代码讲解: 导包和声明对象,设置Spark配置对象和SparkContext对象。 使用Spark S…...
【目标检测】对YOLO系列发展的简单理解
目录 1.YOLOv12.YOLOv23.YOLOv34.YOLOv45.YOLOv66.YOLOv77.YOLOv9 YOLO系列文章汇总: 【论文#目标检测】You Only Look Once: Unified, Real-Time Object Detection 【论文#目标检测】YOLO9000: Better, Faster, Stronger 【论文#目标检测】YOLOv3: An Incremental …...
前端框架的“快闪“时代:我们该如何应对技术迭代的洪流?
引言:前端开发者的"框架疲劳" “上周刚学完Vue 3的组合式API,这周SolidJS又火了?”——这恐怕是许多前端开发者2023年的真实心声。前端框架的迭代速度已经达到了令人目眩的程度,GitHub每日都有新框架诞生,n…...
深度学习训练中的显存溢出问题分析与优化:以UNet图像去噪为例
最近在训练一个基于 Tiny-UNet 的图像去噪模型时,我遇到了经典但棘手的错误: RuntimeError: CUDA out of memory。本文记录了我如何从复现、分析,到逐步优化并成功解决该问题的全过程,希望对深度学习开发者有所借鉴。 训练数据&am…...
Python爬虫实战:获取优志愿专业数据
一、引言 在信息爆炸的当下,数据成为推动各领域发展的关键因素。优志愿网站汇聚了丰富的专业数据,对于教育研究、职业规划等领域具有重要价值。然而,为保护自身数据和资源,许多网站设置了各类反爬机制。因此,如何高效、稳定地从优志愿网站获取计算机专业数据成为一个具有…...
2025.4.22学习日记 JavaScript的常用事件
在 JavaScript 里,事件是在文档或者浏览器窗口中发生的特定交互瞬间,例如点击按钮、页面加载完成等等。下面是一些常用的事件以及案例: 1. click 事件 当用户点击元素时触发 const button document.createElement(button); button.textCo…...
如何修复WordPress中“您所关注的链接已过期”的错误
几乎每个管理WordPress网站的人都可能遇到过“您关注的链接已过期”的错误,尤其是在上传插件或者主题的时候。本文将详细解释该错误出现的原因以及如何修复,帮助您更好地管理WordPress网站。 为什么会出现“您关注的链接已过期”的错误 为了防止资源被滥…...
从零开始搭建Django博客①--正式开始前的准备工作
本文主要在Ubuntu环境上搭建,为便于研究理解,采用SSH连接在虚拟机里的ubuntu-24.04.2-desktop系统搭建的可视化桌面,涉及一些文件操作部分便于通过桌面化进行理解,最后的目标是在本地搭建好系统后,迁移至云服务器并通过…...
健身房管理系统(springboot+ssm+vue+mysql)含运行文档
健身房管理系统(springbootssmvuemysql)含运行文档 健身房管理系统是一个全面的解决方案,旨在帮助健身房高效管理其运营。系统提供多种功能模块,包括会员管理、员工管理、会员卡管理、教练信息管理、解聘管理、健身项目管理、指导项目管理、健身器材管理…...
Java从入门到“放弃”(精通)之旅——继承与多态⑧
Java从入门到“放弃”(精通)之旅🚀——继承与多态⑧ 一、继承:代码复用的利器 1.1 为什么需要继承? 想象一下我们要描述狗和猫这两种动物。如果不使用继承,代码可能会是这样: // Dog.java pu…...
DeepSeek开源引爆AI Agent革命:应用生态迎来“安卓时刻”
开源低成本:AI应用开发进入“全民时代” 2025年初,中国AI领域迎来里程碑事件——DeepSeek开源模型的横空出世,迅速在全球开发者社区掀起热潮。其R1和V3模型以超低API成本(仅为GPT-4o的2%-10%)和本地化部署能力&#x…...
使用 LangChain + Higress + Elasticsearch 构建 RAG 应用
RAG(Retrieval Augmented Generation,检索增强生成) 是一种结合了信息检索与生成式大语言模型(LLM)的技术。它的核心思想是:在生成模型输出内容之前,先从外部知识库或数据源中检索相关信息&…...
深入解析C++ STL List:双向链表的特性与高级操作
一、引言 在C STL容器家族中,list作为双向链表容器,具有独特的性能特征。本文将通过完整代码示例,深入剖析链表的核心操作,揭示其底层实现机制,并对比其他容器的适用场景。文章包含4000余字详细解析,适合需…...
Uniapp:pages.json页面路由
目录 一、pages二、style 一、pages uni-app 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下: 属性类型默认值描述pathString配置页面路径styleObject配置页面窗口表现nee…...
Self-Ask:LLM Agent架构的思考模式 | 智能体推理框架与工具调用实践
作为程序员,我们习惯将复杂问题分解为可管理的子任务,这正是递归和分治算法的核心思想。那么,如何让AI模型也具备这种结构化思考能力?本文深入剖析Self-Ask推理模式的工作原理、实现方法与最佳实践,帮助你构建具有清晰…...
【前端】【业务场景】【面试】在网页开发中,如何优化图片以提高页面加载速度?解决不同设备屏幕适配问题
📌 问题 1:在网页开发中,如何优化图片以提高页面加载速度? 🔍 一、关键词总结 关键词说明图片压缩借助 TinyPNG、ImageOptim 等工具,无损减小图片文件大小格式选择JPEG(照片类)、P…...
Git Flow分支模型
经典分支模型(Git Flow) 由 Vincent Driessen 提出的 Git Flow 模型,是管理 main(或 master)和 dev 分支的经典方案: main 用于生产发布,保持稳定; dev 用于日常开发,合并功能分支(feature/*); 功能开发在 feature 分支进行,完成后合并回 dev; 预发布分支(rele…...
安装 vmtools
第2章 安装 vmtools 1.安装 vmtools 的准备工作 1)现在查看是否安装了 gcc 查看是否安装gcc 打开终端 输入 gcc - v 安装 gcc 链接:https://blog.csdn.net/qq_45316173/article/details/122018354?ops_request_misc&request_id&biz_id10…...
【论文阅读20】-CNN-Attention-BiGRU-滑坡预测(2025-03)
这篇论文主要探讨了基于深度学习的滑坡位移预测模型,结合了MT-InSAR(多时相合成孔径雷达干涉测量)观测数据,提出了一种具有可解释性的滑坡位移预测方法。 [1] Zhou C, Ye M, Xia Z, et al. An interpretable attention-based deep…...
滑动窗口学习
2090. 半径为 k 的子数组平均值 题目 问题分析 给定一个数组 nums 和一个整数 k,需要构建一个新的数组 avgs,其中 avgs[i] 表示以 nums[i] 为中心且半径为 k 的子数组的平均值。如果在 i 前或后不足 k 个元素,则 avgs[i] 的值为 -1。 思路…...
用户需求报告、系统需求规格说明书、软件需求规格说明的对比分析
用户需求报告、系统需求规格说明书(SyRS)和软件需求规格说明书(SRS)是需求工程中的关键文档,分别对应不同层次和视角的需求描述。以下是它们的核心区别对比: 1. 用户需求报告(User Requirem…...
# 基于PyTorch的食品图像分类系统:从训练到部署全流程指南
基于PyTorch的食品图像分类系统:从训练到部署全流程指南 本文将详细介绍如何使用PyTorch框架构建一个完整的食品图像分类系统,涵盖数据预处理、模型构建、训练优化以及模型保存与加载的全过程。 1. 系统概述 本系统实现了一个基于卷积神经网络(CNN)的…...
v-html 显示富文本内容
返回数据格式: 只有图片名称 显示不出完整路径 解决方法:在接收数据后手动给img格式的拼接vite.config中的服务器地址 页面: <el-button click"">获取信息<el-button><!-- 弹出层 --> <el-dialog v-model&…...
【数学建模】孤立森林算法:异常检测的高效利器
孤立森林算法:异常检测的高效利器 文章目录 孤立森林算法:异常检测的高效利器1 引言2 孤立森林算法原理2.1 核心思想2.2 算法流程步骤一:构建孤立树(iTree)步骤二:构建孤立森林(iForest)步骤三:计算异常分数 3 代码实现…...
<项目代码>YOLO小船识别<目标检测>
项目代码下载链接 YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN)࿰…...
Crawl4AI:打破数据孤岛,开启大语言模型的实时智能新时代
当大语言模型遇见数据饥渴症 在人工智能的竞技场上,大语言模型(LLMs)正以惊人的速度进化,但其认知能力的跃升始终面临一个根本性挑战——如何持续获取新鲜、结构化、高相关性的数据。传统数据供给方式如同输血式营养支持ÿ…...
AI 技术发展:从起源到未来的深度剖析
一、AI 的起源与早期发展 人工智能(AI)作为计算机科学的重要分支,其诞生可以追溯到 20 世纪中叶。1943 年,艾伦・图灵提出图灵机的概念,为计算机科学和 AI 理论奠定了基础。1950 年,图灵又提出著名的图灵…...
jsconfig.json文件的作用
jsconfig.json文件的作用 为什么今天会谈到这个呢?有这么一个场景:我们每次开发项目时都会给路径配置别名,配完别名之后可以简化我们的开发,但是随之而来的就有一个问题,一般来说,当我们使用相对路径时…...

















