深入解析Java泛型:从定义到实战应用
目录
- 🚀前言
- 🤔泛型的定义
- 🐧泛型类
- 🌟泛型接口
- ✍️泛型方法、通配符、上下限
- 💯泛型方法
- 💯 通配符与上下限
- ⚙️通配符(Wildcard)
- ⚙️泛型上下限
- ⚙️应用场景
- 🦜泛型支持的类型
- ⚙️泛型擦除
- 💯包装类
- ⚙️自动装箱与自动拆箱
- ⚙️常用功能
- ⚙️应用场景
🚀前言
大家好!我是 EnigmaCoder。
本文主要介绍java泛型部分,包含泛型的定义、泛型类、泛型接口、泛型方法、通配符、上下限等。
🤔泛型的定义
定义类、接口、方法时,同时声明了一个或者多个类型变量(如:<E>
),则称为泛型类、泛型接口、泛型方法,它们统称为泛型。
例如:
public class ArrayList<E>{...
}
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力。这样可以避免强制类型转换,及其可能出现的异常。
代码示例:
public class Test {public static void main(String[] args) {ArrayList <String>list = new ArrayList<String>();list.add("hello");list.add("world");list.add(23);for(String str:list){System.out.println(str);}}
}
- 由于使用了泛型,这段代码中
list.add(23);
会报错,只能使用String
类型。如果不使用泛型,则遍历时需要进行强制类型转换,容易出现异常。- 泛型的本质:把具体的数据类型作为参数传给类型变量。
🐧泛型类
在Java中,泛型类是一种可以操作多种数据类型的类,它通过类型参数化来实现代码的复用和类型安全。泛型类的定义格式如下:
修饰符 class 类名<类型变量,类型变量,...>{
}
注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V
等。
代码示例:
public class Box<T> {private T item;public void setItem(T item) {this.item = item;}public T getItem() {return item;}
}
Box
是一个泛型类,类型参数为T
。item
是Box
类的一个私有成员变量,类型为T
。setItem
方法用于设置item
的值,参数类型为T
。getItem
方法用于获取item
的值,返回类型为T
。
使用场景:
泛型类在需要处理多种数据类型时非常有用,特别是在集合类中。例如,Java
标准库中的ArrayList
、HashMap
等都是泛型类。通过使用泛型类,可以避免类型转换的麻烦,并提高代码的类型安全性。
🌟泛型接口
在Java
中,泛型接口是一种允许在接口定义中使用类型参数的机制。通过使用泛型接口,可以创建更加灵活和可重用的代码,因为它允许接口方法操作多种类型的数据,而不需要为每种类型都编写一个单独的接口。
格式如下:
修饰符 interface 接口<类型变量,类型变量...>{...
}
注意:同样建议使用大写英文字母,如:E、T、K、V
等。
代码示例
:
public interface Box<T> {void add(T item);T get();
}
public class StringBox implements Box<String> {private String item;@Overridepublic void add(String item) {this.item = item;}@Overridepublic String get() {return item;}
}
- 在这个例子中,
StringBox
类实现了Box
接口,并指定类型参数为String
。因此,add
方法接受一个String
类型的参数,get
方法返回一个String
类型的值。- 泛型接口是Java中一种强大的工具,它允许开发者编写更加通用和可重用的代码。通过使用泛型接口,可以避免为每种数据类型编写单独的接口,从而提高代码的灵活性和可维护性。在实际开发中,泛型接口广泛应用于集合框架、回调机制、数据存储等场景。
✍️泛型方法、通配符、上下限
💯泛型方法
泛型方法是Java
中一种强大的特性,它允许在方法中使用类型参数,从而使方法能够处理多种类型的数据,而不需要为每种类型编写单独的方法。泛型方法在集合框架、工具类等场景中广泛应用,能够提高代码的复用性和类型安全性。
格式如下:
修饰符<类型变量,类型变量,...>返回值类型 方法名(形参列表){...
}
代码示例:
public class GenericMethodExample {// 定义一个泛型方法public static <T> void printValue(T value) {System.out.println("Value: " + value);}public static void main(String[] args) {// 调用泛型方法,传入不同类型的参数printValue("Hello, World!"); // 输出: Value: Hello, World!printValue(123); // 输出: Value: 123printValue(3.14); // 输出: Value: 3.14}
}
💯 通配符与上下限
在Java
泛型编程中,通配符和上下限是处理泛型类型的重要概念,它们提供了更灵活的类型处理方式。
⚙️通配符(Wildcard)
通配符用“?
”表示,它可以在使用泛型时代表任意类型。通配符通常用于泛型方法的参数类型或泛型类的类型参数中,以增加代码的灵活性。例如,在定义一个方法时,如果希望该方法能够接受任何类型的List
,可以使用通配符:
public void printList(List<?> list) {for (Object elem : list) {System.out.println(elem);}
}
在这个例子中,List<?>
表示可以接受任何类型的List,无论是List<String>
、List<Integer>
还是其他类型的List。
⚙️泛型上下限
泛型上下限用于限制泛型类型的范围,使得泛型类型更加安全和可控。
- 泛型上限(
Upper Bound
)
泛型上限使用? extends T
表示,其中T
是一个具体的类或接口。它表示泛型类型必须是T
或其子类。例如:
public void processCars(List<? extends Car> cars) {for (Car car : cars) {car.drive();}
}
在这个例子中,List<? extends Car>
表示cars
列表中的元素必须是Car
类或其子类(如SportsCar
或SUV
)。这样可以确保在processCars
方法中,所有元素都至少具有Car
类的方法。
- 泛型下限(
Lower Bound
)
泛型下限使用? super T
表示,其中T
是一个具体的类或接口。它表示泛型类型必须是T
或其父类。例如:
public void addCar(List<? super Car> cars, Car car) {cars.add(car);
}
在这个例子中,List<? super Car>
表示cars
列表中的元素必须是Car
类或其父类(如Vehicle
)。这样可以确保在addCar
方法中,可以向列表中添加Car
对象或其子类对象。
⚙️应用场景
- 通配符:适用于需要处理多种类型但不需要知道具体类型的场景,如通用的集合处理方法。
- 泛型上限:适用于需要限制类型为某个类或其子类的场景,如处理特定类及其子类的集合。
- 泛型下限:适用于需要限制类型为某个类或其父类的场景,如向集合中添加特定类或其子类的对象。
通过合理使用通配符和泛型上下限,可以使泛型代码更加灵活、安全和易于维护。
🦜泛型支持的类型
在Java中,泛型是一种强大的特性,它允许在定义类、接口和方法时使用类型参数。然而,泛型有一个重要的限制:它不支持基本数据类型(如int、char、boolean
等),只能支持对象类型(即引用数据类型,如Integer、String、List
等)。这是因为泛型的实现机制依赖于Java的类型系统,而基本数据类型并不属于对象类型。
⚙️泛型擦除
-
泛型在Java中的实现是通过一种称为“泛型擦除”的机制来完成的。泛型擦除意味着泛型信息只在编译阶段有效,而在编译后的字节码中,所有的泛型类型参数都会被替换为它们的上界(通常是Object类型)。因此,在运行时,泛型类型信息是不可用的。例如,
List<String>
在编译后会被擦除为List<Object>
,这意味着在运行时,你无法通过反射等方式获取到List
中元素的类型信息。 -
这种设计的主要目的是为了保持与
Java
早期版本的兼容性,因为泛型是在Java 5
中引入的,而在此之前,Java
的集合类都是使用Object
类型来存储元素的。
💯包装类
由于泛型不支持基本数据类型,Java提供了包装类(Wrapper Classes)来将基本数据类型包装成对象类型。包装类位于java.lang
包中,每个基本数据类型都有对应的包装类,例如Integer
对应int
,Double
对应double
,Boolean
对应boolean
等。
基本数据类型 | 包装类 | 默认值 | 字节数 | 最小值 | 最大值 |
---|---|---|---|---|---|
byte | Byte | 0 | 1 | -128 | 127 |
short | Short | 0 | 2 | -32,768 | 32,767 |
int | Integer | 0 | 4 | -2,147,483,648 | 2,147,483,647 |
long | Long | 0L | 8 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
float | Float | 0.0F | 4 | 1.4E-45 | 3.4028235E38 |
double | Double | 0.0D | 8 | 4.9E-324 | 1.7976931348623157E308 |
char | Character | '\u0000' | 2 | '\u0000' (0) | '\uffff' (65,535) |
boolean | Boolean | false | - | false | true |
⚙️自动装箱与自动拆箱
Java 5
引入了自动装箱(Autoboxing
)和自动拆箱(Unboxing
)机制,使得基本数据类型和它们的包装类之间的转换更加方便。
-
自动装箱:当需要将一个基本数据类型赋值给一个包装类对象时,Java会自动将基本数据类型转换为对应的包装类对象。例如:
Integer i = 10; // 自动装箱,int 10 被转换为 Integer 对象
-
自动拆箱:当需要将一个包装类对象赋值给一个基本数据类型变量时,Java会自动将包装类对象转换为对应的基本数据类型。例如:
int j = i; // 自动拆箱,Integer 对象 i 被转换为 int 类型
⚙️常用功能
包装类不仅提供了基本数据类型与对象类型之间的转换功能,还提供了一些常用的实用方法:
-
将基本数据类型转换为字符串:每个包装类都提供了
toString()
方法,可以将基本数据类型的数据转换为字符串。例如:int num = 123; String str = Integer.toString(num); // 将 int 转换为字符串 "123"
-
将字符串转换为基本数据类型:包装类还提供了
parseXxx()
方法,可以将字符串类型的数值转换为对应的基本数据类型。例如:String str = "456"; int num = Integer.parseInt(str); // 将字符串 "456" 转换为 int 类型
-
其他实用方法:包装类还提供了一些其他实用方法,如
valueOf()
、compareTo()
、equals()
等,用于处理基本数据类型的比较、转换等操作。
⚙️应用场景
包装类在Java编程中有着广泛的应用,特别是在需要使用泛型或集合类时。例如,当你需要在List
中存储整数时,由于泛型不支持基本数据类型,你必须使用Integer
包装类:
List<Integer> numbers = new ArrayList<>();
numbers.add(10); // 自动装箱,int 10 被转换为 Integer 对象
int firstNumber = numbers.get(0); // 自动拆箱,Integer 对象被转换为 int 类型
此外,包装类在处理数据库操作、网络通信等场景中也经常被使用,因为这些场景通常需要将数据以对象的形式进行传递和处理。
通过使用包装类,Java
程序员可以更加灵活地处理基本数据类型和对象类型之间的转换,从而编写出更加健壮和可维护的代码。
相关文章:

深入解析Java泛型:从定义到实战应用
目录 🚀前言🤔泛型的定义🐧泛型类🌟泛型接口✍️泛型方法、通配符、上下限💯泛型方法💯 通配符与上下限⚙️通配符(Wildcard)⚙️泛型上下限⚙️应用场景 🦜泛型支持的类…...

【开源】一个基于 Vue3 和 Electron 开发的第三方网易云音乐客户端,具有与官方客户端相似的界面布局
🎵 XCMusic:高颜值第三方网易云音乐客户端 🎶 📍 项目亮点 XCMusic 是一款基于Vue3Electron开发的开源、跨平台网易云音乐客户端。 此音乐播放器基于 Electron 开发,旨在为用户提供简洁、美观、兼容多平台的音乐体验。…...
【云实验】Excel文件转存到RDS数据库
实验名称:Excel文件转存到RDS数据库 说明:把Excel的数据通过数据管理服务DMS(Data Management Service)导入到RDS MySQL数据库中。 流程:创建一个RDS for MySQL的实例,再创建数据库和账号,通过D…...
从零开始:用Python语言基础构建宠物养成游戏:从核心知识到完整实战
一、代码分段拆解与知识点映射 1. 初始化游戏数据:变量与数据类型的综合应用 # 用字典存储宠物信息(嵌套字典数字/字符串类型) pet {"name": "小雪", # 字符串:宠物名字"age": 1, …...

labview设计一个虚拟信号发生器
目标:设计一个虚拟信号发生器,通过功能键的设置可以产生正弦波、三角波、方波和锯齿波,并可以通过输入控件设置采集信号的频率、幅值、相位等参数。 一、正弦波 (1)创建一个枚举 (2)点击属性后…...

工业路由器WiFi6+5G的作用与使用指南,和普通路由器对比
工业路由器的技术优势 在现代工业环境中,网络连接的可靠性与效率直接影响生产效率和数据处理能力。WiFi 6(即802.11ax)和5G技术的结合,为工业路由器注入了强大的性能,使其成为智能制造、物联网和边缘计算的理想选择。…...
Chrome 插件网络请求的全面指南
在 Chrome 插件开发中,网络请求可以在多个上下文中实现,而不仅限于 background.js 和 content.js。以下是完整的网络请求实现方案: 一、主要请求实现位置 1. Background Script (后台脚本) 特点: 生命周期最长适合处理敏感数据…...

编译Qt5.15.16并启用pdf模块
编译Qt5.15.16并启用pdf模块 标题1.目录设置 -q-bulid –qt-everywhere-src-5.15.16 –bulid cd bulid 必须,否则会提示Project ERROR: You cannot configure qt separately within a top-level build. create .qmake.stash and .qmake.super in build folder …...

Python绘制新冠疫情的知识图谱
from pyvis.network import Network import networkx as nx import pandas as pd import os# 修复模板路径 from pyvis import network as net_moduleos.environ["PATH"] os.pathsep os.path.dirname(net_module.__file__)# 创建紧密连接图 g nx.Graph()# 关键修…...
canvas(三)-动画3d
在 <canvas> 中实现 3D 动画通常需要借助 WebGL 技术,因为原生的 2D 上下文(CanvasRenderingContext2D)无法直接支持 3D 渲染。WebGL 是基于 OpenGL ES 2.0 的 JavaScript API,可以直接在浏览器中实现高性能的 3D 图形渲染。…...

使用RUST在Arduino上进行编程(MacOS,mega板)
近年来,RUST成为了嵌入式编程的热门语言,本文通过实现(1)LED闪灯,以及(2)在console(终端)实现“Hello Rust World”两项功能来完成实操的入门。 深入学习可以参考RUST语言…...
MySQL迁移SSL报错
文章记录了之前tdsql迁移IDC过程中遇到的小问题 环境 xboss业务: tdsql未启用SSL, IDC-mysql启用了SSL: 原因分析 1, 迁移前: 因为tdsql未启用ssl, 且应用未显式配置ssl JDBC默认使用非SSL连接,因此可以正…...

大模型微调与高效训练
随着预训练大模型(如BERT、GPT、ViT、LLaMA、CLIP等)的崛起,人工智能进入了一个新的范式:预训练-微调(Pre-train, Fine-tune)。这些大模型在海量数据上学习到了通用的、强大的表示能力和世界知识。然而,要将这些通用模型应用于特定的下游任务或领域,通常还需要进行微调…...
LLM驱动的未来软件工程范式与架构策略
历史回顾与范式奠基 软件工程自其诞生以来,经历了数次里程碑式的范式变革。最初的汇编语言时代,程序员与机器指令直接对话,效率低下,代码难以复用。随后,高级语言(如Fortran、C)的出现,通过抽象层极大地提升了开发效率,并催生了面向过程的编程范式。进入20世纪末,面…...

OpenCv高阶(十六)——Fisherface人脸识别
文章目录 前言一、Fisherface人脸识别原理1. 核心思想:LDA与Fisher准则2. 实现步骤(1) 数据预处理(2) 计算类内散布矩阵 SW对每个类别(每个人)计算均值向量 μi:(3) 计算类间散布矩阵 SB(4) 求解投影矩阵 W(5) 降维与分类 3. Fish…...
Unity3D 异步加载材质显示问题排查
前言 在Unity3D中异步加载材质后未正确显示的问题,通常涉及资源加载流程、材质引用或Shader配置。以下是逐步排查和解决问题的方案: 对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀! …...
【Django Serializer】一篇文章详解 Django 序列化器
第一章 Django 序列化器概述 1.1 序列化器的定义 1.1.1 序列化与反序列化的概念 1. 序列化 想象你有一个装满各种物品(数据对象)的大箱子(数据库),但是你要把这些物品通过一个狭窄的管道(网络ÿ…...

二分算法的补充说明
在上一节中我们简单介绍了二分算法,通过区分小于等于,大于或者小于,大于等于我们可以求出它们的边界值。 具体方法是先看一下要求哪里的边界值,分成两部分让如果求小于等于的右边界,我们根据条件让rightmid-1,leftmid…...
C++:array容器
array容器是序列容器,它的特点是:静态,固定数目。可以看作更安全的数组。 它还有一些成员函数,如begin():返回指向容器中第一个元素的随机访问迭代器。 #include<iostream>//数组容器 #…...
java每日精进 5.19【Excel 导入导出】
基于 EasyExcel 实现 Excel 的读写操作,可用于实现最常见的 Excel 导入导出等功能。 Excel 导入导出功能涉及前后端协作,后端处理数据查询、文件生成和解析,前端提供用户交互和文件下载/上传界面。以下是全流程解析,分为导出流程…...

java基础(api)
包: 导包,不同包的程序名相同。 但是要用两个的话可以这样子写: String String概述 String的常用方法 String使用时的注意事项 String的应用案例...
CentOS7/Ubuntu SSH配置允许ROOT密码登录
CentOS7 打开SSHD配置文件 vim /etc/ssh/sshd_config 找到注释行,如果没有就添加。 #PermitRootLogin yes 把注释取消掉。 执行下述命令,重启SSHD服务即可。 systemctl restart sshd.service Ubuntu 先安装SSH服务器,CentOS7默认就安…...
C++ HTTP框架推荐
1. Crow 特点:高性能异步框架,支持Linux、macOS和Windows 优势: 轻量级:整个框架只有一个头文件,易于集成到项目中 简单易用:API设计简洁直观,学习曲线平缓 高性能:基于Boost.Asi…...
算法打卡第二天
5.爬楼梯(动态规划) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2…...

VSCode推出开源Github Copilot:AI编程新纪元
文章目录 开源决策的背后GitHub Copilot的演进历程Copilot Chat核心功能解析1. 聊天界面集成2. 代码理解与生成3. 多文件编辑能力4. 智能代理模式 开源后的影响与展望对开发者的影响对AI编程工具市场的影响未来发展方向 如何开始使用GitHub Copilot结语相关学习资源 在AI编程助…...

Mujoco 学习系列(四)官方模型仓库 mujoco_menagerie
mujoco 官方在 Github 上发布了一个他们自己整理的高质量的模型仓库,这个仓库是一个持续维护的项目,里面包含了目前市面上常见的人形机器人、机械臂、底盘等模型,对于初学者而言是一个非常好的学习资料,无论是想在仿真环境中尝试还…...

代码走读 Go 语言 Map 的实现
序言 在日常的开发当中,我们一定离不开一个数据结构字典。不仅可以存储关联数据对,还可以在 O(1) 的时间复杂度进行查找。很久之前在 一篇文章带你实现 哈希表 介绍了相关的原理以及简单的实现。所以这篇文章中我们就不多赘述哈希表的原理,而…...

PostgreSQL14 +patroni+etcd+haproxy+keepalived 集群部署指南
使用postgresql etcd patroni haproxy keepalived可以实现PG的高可用集群,其中,以postgresql做数据库,Patroni监控本地的PostgreSQL状态,并将本地PostgreSQL信息/状态写入etcd来存储集群状态,所以,patr…...

数据结构知识点汇总
1、在数据结构中,随机访问是指能够直接访问任一元素,而不需要从特定的起始位置开始,也不需要按顺序访问其他元素。这种访问方式通常不涉及遍历。例如,数组(array)支持随机访问,你可以直接通过索…...
雅思英语考试基本介绍
考试分类 雅思(国际英语语言测试系统,International English Language Testing System 即IELTS)主要分为两大类: 学术类(A类) 这是我可能会选择的一种(✓),专为申请大学…...