Java泛型:灵活多变的类型参数化工具

- 👑专栏内容:Java
- ⛪个人主页:子夜的星的主页
- 💕座右铭:前路未远,步履不停
目录
- 一、泛型
- 1、什么是泛型
- 2、泛型的语法
- 二、泛型类的使用
- 1、泛型类的语法
- 2、泛型如何编译的
- 2.1、擦除机制
- 2.2、为什么不能实例化泛型类型数组
- 3、泛型方法
一、泛型
1、什么是泛型
在传统的编程方法中,类和方法通常被限定为使用特定的类型。这些类型可能是基础的数据类型(如整数、字符等),或者是由程序员自己定义的复杂类型。这种方式在处理单一类型数据时很有效,但当我们需要编写更加灵活、能够适用于多种数据类型的代码时,这种严格的类型限制就变成了一个约束。
泛型,就是为了解决这种限制而生的。简单来说,泛型可以理解为一种“类型模板”,它允许程序员编写的代码能够适应不同的数据类型,而不必为每种可能的数据类型都编写一个新版本。
泛型的厉害之处,就在于它的灵活性和重用性。你可以写一个泛型方法或类,然后在需要的时候用具体的类型去实例化它,比如整数、字符串或者是你自定义的任何类型。这样,你就可以用同一套代码处理不同类型的数据,极大地提高了代码的通用性和可维护性。
2、泛型的语法
泛型的基本语法主要包括以下几个方面:
-
泛型类和接口:
- 在类或接口后面加上
<T>来声明一个泛型类或接口。 T是类型参数,代表一种未指定的类型。在实例化类或接口时,你可以用具体的类型替换它。- 示例:
public class Box<T> {private T t;public void set(T t) {this.t = t;}public T get() {return t;} }
这个例子中,
Box类可以用任何类型的对象来实例化,例如Box<Integer>或Box<String>。 - 在类或接口后面加上
-
泛型方法:
- 泛型方法可以定义在普通类中,也可以定义在泛型类中。
- 在方法返回类型之前使用
<T>来声明一个泛型方法。 - 示例:
public <T> T genericMethod(T t) {return t; }
这个方法可以接受任何类型的参数,并返回相同类型的对象。
-
类型通配符:
- 使用
?表示未知类型,通常用在参数、字段、局部变量上,以及泛型方法的返回类型上。 - 示例:
public void processElements(List<?> elements) {for (Object e : elements) {// 处理e} }
List<?>可以接受任何类型的List。 - 使用
-
限定的类型参数:
- 你可以限制类型参数可以接受的类型范围。
- 使用
extends关键字来限定类型参数的上界(即它必须是特定类或接口的子类型)。 - 示例:
public <T extends Number> double sum(List<T> numbers) {double sum = 0.0;for (Number n : numbers) {sum += n.doubleValue();}return sum; }
这个方法只接受Number类型或其子类的List。
泛型存在的意义:
- 在编译的时候,帮我们进行类型的检查。
- 在编译的时候,帮我们进行类型的转换。
二、泛型类的使用
1、泛型类的语法
泛型类<类型实参> 变量名; // 定义一个泛型类引用new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
MyArray<Integer> list = new MyArray<Integer>();
注意:泛型只能接受类,所有的基本数据类型必须使用包装类!
2、泛型如何编译的
2.1、擦除机制

在编译时,Java编译器将所有的泛型类型参数替换掉,这个过程就是类型擦除。
- 泛型类型参数被替换为它们的边界或者
Object。 - 如果类型参数是有界的(
<T extends Number>),编译器将类型参数替换为它的第一个边界。 - 如果类型参数是无界的(
<T>),编译器将类型参数替换为Object。
Java的泛型机制是在编译级别实现的,编译器生成的字节码在运行期间并不包含泛型的类型信息。
2.2、为什么不能实例化泛型类型数组
class MyArray<T> {public T[] array = (T[])new Object[10];public T getPos(int pos) {return this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}public T[] getArray() {return array;}
}public class demo1 {public static void main(String[] args) {MyArray<Integer> myArray1 = new MyArray<>();Integer[] strings = myArray1.getArray();}
}

由于类型擦除的原因,不能直接创建一个泛型数组。类型擦除会将泛型类型参数T替换为Object,这导致了类型不匹配,从而在运行时抛出ClassCastException。
3、泛型方法
语法:方法限定符 <类型形参列表> 返回值类型 方法名称(形参列表) { ... }
例子:写一个泛型方法,用于交换数组中两个元素的位置:
public class GenericMethodTest {// 泛型方法 printArraypublic static < E > void printArray( E[] inputArray ) {for(E element : inputArray) {System.out.printf("%s ", element);}System.out.println();}public static void main(String args[]) {// 创建不同类型数组: Integer, Double 和 CharacterInteger[] intArray = { 1, 2, 3, 4, 5 };Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };System.out.println("整型数组元素为:");printArray(intArray); // 传递一个整型数组System.out.println("\n双精度型数组元素为:");printArray(doubleArray); // 传递一个双精度型数组System.out.println("\n字符型数组元素为:");printArray(charArray); // 传递一个字符型数组}
}
- 泛型方法可以声明在普通类或泛型类中。
- 泛型方法的声明包括一个类型参数部分,跟在方法的修饰符和返回类型之前。
- 类型参数部分是一个尖括号括起来的类型参数列表,如
<T>。
相关文章:
Java泛型:灵活多变的类型参数化工具
👑专栏内容:Java⛪个人主页:子夜的星的主页💕座右铭:前路未远,步履不停 目录 一、泛型1、什么是泛型2、泛型的语法 二、泛型类的使用1、泛型类的语法2、泛型如何编译的2.1、擦除机制2.2、为什么不能实例化泛…...
java 体育明星管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 java Web 体育明星管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysq…...
蓝凌EIS智慧协同平台 ShowUserInfo.aspx sql注入漏洞
漏洞描述: 蓝凌EIS智慧协同平台是一个简单、高效的工作方式专为成长型企业打造的沟通、协同、社交的移动办公平台,覆盖OA、沟通、客户、人事、知识等管理需求,集合了非常丰富的模块,满足组织企业在知识、项目管理系统建设等需求的…...
React Hooks的useState、useRef使用
React Hooks 是 React 16.8 版本引入的新特性,它允许你在不编写 class 的情况下使用 state 和其他 React 特性。其中,useState 和 useRef 是两个常用的 Hooks。 1. useState useState 是一个允许你在函数组件中添加 state 的 Hook。 使用说明…...
Linux--防火墙,实验案例:基于区域、服务、端口的访问控制
实验环境 某公司的Web服务器,网关服务器均采用Linux CentOS 7.3操作系统,如图2.13所示。为了 加强网络访问的安全性,要求管理员熟悉firewalld防火墙规则的编写,以便制定有效、可行的主机防护策略。 需求描述 > 网关服务器ens3…...
C++学习笔记(二十八):c++ 静态库及动态库的使用
静态库的使用 库的使用会很大程度减少我们的工作,本节对c中静态库和动态库的使用进行简单的介绍。静态链接库意味着这个库会被放到可执行文件中,在生成的exe中。动态链接库是在程序运行时链接的,可以在程序运行时调用加载库函数的方法来实现&…...
uniapp最简单的底部兼容安全区域显示
效果图: 1.html写上动态padding-bottom <view class"button-wrap" :style"padding-bottom:bottomPaddingrpx"><view class"com-btn cencel-btn">取消</view><view class"com-btn confirm-btn " cl…...
图像去噪——CBDNet网络训练自己数据集及推理测试,模型转ONNX模型(详细图文教程)
CBDNet 主要由两个子网络组成:噪声估计子网络和去噪子网络。噪声估计子网络用于估计图像的噪声水平,而去噪子网络用于去除图像中的噪声。 CBDNet 的优势在于: 它采用了更真实的噪声模型,既考虑了泊松-高斯模型,还考虑…...
【Verilog】期末复习——解释下列名词(FPGA、ASIC、IP、RTL、EDA、HDL、FSM)
系列文章 数值(整数,实数,字符串)与数据类型(wire、reg、mem、parameter) 运算符 数据流建模 行为级建模 结构化建模 组合电路的设计和时序电路的设计 有限状态机的定义和分类 期末复习——数字逻辑电路分…...
计算机网络 综合(习题)
【计算机网络习题】系列文章目录 计算机网络 第一章 绪论(习题) 计算机网络 第二章 计算机网络体系结构(习题) 计算机网络 第三章 应用层(习题) 计算机网络 第四章 运输层(习题) 计算机网络 第五章 网络层(习题) 计算机网络 第六章 数据链路层(习题) 计算机网络 第七章 物…...
探索vue2框架的世界:简述常用的vue2选项式API (二)
组件实例 👉 $attrs 用于父组件隔代向孙组件传值 长设置在子组件中 v-bind"$attrs" (Vue2.4) parent.vue (父组件) <template><div class"outer"><h3>父组件</h3>名字:<input v-model"name"…...
云计算:OpenStack 分布式架构管理FLAT网络(单控制节点与多计算节点)
目录 一、实验 1.环境 2.控制节点创建网络 3.控制节点创建规格 4.控制节点新增安全组入口规则 5.控制节点创建实例 二、问题 1.FLAT网络底层如何实现 2.无法SSH 云主机实例 一、实验 1.环境 (1) 主机 表1 主机 主机架构IP备注controller控制节点192.168.204.210已部…...
【深度学习】cv领域中各种loss损失介绍
文章目录 前言一、均方误差二、交叉熵损失三、二元交叉熵损失四、Smooth L1 Loss五、IOU系列的loss 前言 损失函数是度量模型的预测输出与真实标签之间的差异或误差,在深度学习算法中起着重要作用。具体作用: 1、目标优化:损失函数是优化算法…...
2024年,为什么学网络安全找不到工作?这才是重要原因!
为什么网络安全人才缺口那么大,但很多人还是找不到工作?其实大家都忽略了1个重点,那就是不清楚企业在招什么样的人。 我花了2天的时间统计了主流招聘网站的岗位信息,发现了一个惊人的真相,那就是企业都喜欢招这3种人&a…...
很有用!小企业如何从零开始制作产品手册?
对于初创公司和小企业来说,创造一份高效、吸引人的产品手册可能不是特别简单,特别是当资源和预算有限的时候。然而,一份良好的产品手册可以帮助你传达你的品牌故事,展示你的产品,甚至可以帮助你提高销售额,…...
基于OpenCV的图像缩放
基础概念 缩放是将图像的尺寸变小或变大的过程,即减少或增加原图像数据的像素个数,或者说通过增加或删除像素点来改变图像的尺寸; 基本原理:将分辨率(图片尺寸)为(w,h)的图像,缩放后其图像分辨…...
基于长短期神经网络LSTM的测量误差预测
目录 背影 摘要 代码和数据下载:基于长短期神经网络LSTM的测量误差预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88714812 LSTM的基本定义 LSTM实现的步骤 基于长短期神经网络LSTM的测量误差预测 结果分析 展望 参考论文 背影 …...
`package.json`也可以有注释了
众所周知,JSON文件是不支持注释的,除了JSON5/JSONC之外,我们在开发项目特别是前端项目时,大量会用到JSON文件,特别是在编写package.json中的scripts时,由于缺少注释,当有大量的命令脚本时,就有了…...
数学之何为数学
数学是什么 数学是绝大多数人学得最多的一门功课,但对于“数学是什么?”这一看来很普通的问题,却很难一下子给出一个使公众满意的回答。按照恩格斯的说法,数学是以现实世界的空间形式和数量关系为研究对象的。尽管人们现在对空间…...
docker容器内,将django项目数据库改为postgresql
容器为ubuntu20.04版本,新建了一套django项目,使用的默认sqllit3,换为postgresql,容器里安装postgresql方法 步骤1: 安装PostgreSQL数据库 # 打开一个bash会话在你的容器中 docker exec -it <container_id_or_name> bash#…...
读了libstdc++ std::vector源码,发现你的push_back可能比你想象的慢10倍——6个隐藏的性能陷阱
一、那行push_back到底发生了什么 C++程序员最熟悉的容器是谁?std::vector。 面试要用它,刷题要用它,生产代码里更是到处都是。随手grep一下手头的项目,vector的出现频率是map的4倍、list的12倍、deque的20倍。能用vector的地方,大家默认就用vector——C++ Core Guideli…...
【实战指南】CCPD数据集车牌检测框坐标解析与YOLO格式转换技巧
1. CCPD数据集车牌检测实战入门 第一次接触CCPD数据集时,我被它独特的文件名编码方式吸引了。这个数据集包含了超过30万张真实场景下的车牌图片,每张图片的文件名都像是一个密码本,藏着车牌位置的关键信息。比如"025-95&449_186&…...
STM32驱动GP2Y1014AU粉尘传感器实战指南
1. 认识GP2Y1014AU粉尘传感器 GP2Y1014AU是夏普公司推出的一款光学粉尘传感器,专门用于检测空气中PM2.5等细小颗粒物的浓度。它的工作原理是通过红外LED照射空气中的颗粒物,然后检测散射光的强度来判断粉尘浓度。这种检测方式在空气净化器、环境监测设备…...
龙迅LT6911GXD:解码8K超高清时代,如何用单芯片打通HDMI/DP/USB-C到MIPI/LVDS的显示桥梁?
1. 认识龙迅LT6911GXD:8K时代的接口转换神器 第一次拿到龙迅LT6911GXD芯片时,我正被一个VR头显项目折磨得焦头烂额。客户要求用游戏主机的HDMI 2.1信号驱动MIPI接口的4K 120Hz屏幕,传统方案需要三颗芯片级联,电路板面积比显示屏还…...
【FI】资产主数据屏幕格式(S_ALR_87009044)的字段组配置实战:从OAVN到OAVM
1. 资产主数据屏幕格式配置的核心挑战 第一次接触SAP资产主数据屏幕格式配置时,我被那个没有"新建"和"删除"按钮的界面搞得一头雾水。作为FI顾问,客户经常要求定制资产主数据的显示字段,但系统默认界面就像个黑盒子&…...
亚洲美女-造相Z-Turbo镜像可持续性:支持模型热插拔、多版本共存、灰度发布机制
亚洲美女-造相Z-Turbo镜像可持续性:支持模型热插拔、多版本共存、灰度发布机制 1. 镜像概述与核心特性 亚洲美女-造相Z-Turbo是一个基于Z-Image-Turbo LoRA版本的专业文生图模型,专门针对亚洲女性形象生成进行了深度优化。该镜像通过Xinference框架部署…...
SCI论文投稿全流程解析:从注册到成功提交
1. 投稿前的准备工作 第一次投稿SCI论文就像第一次开车上路,既兴奋又紧张。记得我投第一篇论文时,光是准备阶段就花了整整两周时间,反复检查各种细节。现在回头看,其实只要做好这几个关键准备,就能事半功倍。 选刊是门…...
告别黑盒:手把手教你定制Unity WebGL的加载页面与浏览器交互(模板、JS插件、通信全解析)
深度定制Unity WebGL:从加载界面到浏览器交互的全链路实战指南 1. 为什么需要定制WebGL加载体验? 当用户首次访问基于Unity WebGL构建的网页应用时,默认的灰色进度条和纯白背景往往无法传递产品调性。数据显示,经过视觉优化的加载…...
都在用 Java8 或 Java17,那 Java9 到 16 呢?他们真的没用吗?
刚入行写Java的时候,就在想,为什么很多公司和网上教程用的都是Java8,而不是更新的版本?后来发现大家又开始讨论要不要升级到Java17,或是新项目直接用Java17,但却几乎没看到有人提起中间的9、10、11...这些版…...
Mockito 5.14.1 + JUnit 5实战:多线程环境下静态方法Mock的3种解决方案
Mockito 5.14.1 JUnit 5实战:多线程环境下静态方法Mock的3种解决方案 在金融交易系统或异步任务处理场景中,多线程环境下的单元测试常常成为开发者的噩梦。特别是当我们需要Mock静态方法时,Mockito的传统用法往往在非测试线程中失效——这个…...
