JAVA中的泛型
一、泛型的概念
泛型是JAVA中的一个重要的概念,它允许你在编译时指定数据类型,从而使得代码更加灵活,更加通用。通过泛型,你可以在通用代码上操作不同数据类型,使得代码更加具有通用性。
二、泛型的使用场景
1、泛型接口:
泛型接口允许你定义一个接口,该接口可以应用于不同的数据类型的对象。例如:List是一个接口,但是List可以应用于List、List等。
2、泛型类:
泛型类允许你定义一个类,该类可以应用于不同的数据类型的对象。例如:ArrayList是一个类,但是ArrayList可以应用于ArrayList、ArrayList等。
3、泛型方法:
泛型方法允许你定义一个方法,并在该方法返回值类型前边使用泛型限制,例如:List中的<T> T[] toArray(T[] var1);方法的定义。
4、泛型参数:
泛型参数用来限制方法参数的数据类型,通过泛型参数,可以灵活的处理不同数据类型的参数。例如:List.add可以接收Integer类型的数据,也可以接收String类型的数据。
三、泛型的应用
假设有一个打印场景,传入的打印内容是不确定的,需要根据实际场景去决定,那么此时就需要使用泛型来解决这个问题, 通过泛型,可以定义一个方法,让方法可以接收不同类型的参数
1.1、JavaGenerics.java
/** * java中的泛型使用: * 假设有一个打印场景,传入的打印内容是不确定的,需要根据实际场景去决定,那么此时就需要使用泛型来解决这个问题, * 通过泛型,可以定义一个方法,让方法可以接收不同类型的参数 */
public class JavaGenerics { /** * 测试打印入口: * 如果不使用泛型,那么需要使用两个方法分别打印字符串和数值,如果想要 * 打印其他类型的时候,那么就需要再定义一个方法,这样就会造成代码冗余 */ @Test public void testPrint() { // 单独定义具体的类实现Integer打印 IntegerPrinter integerPrinter = new IntegerPrinter(123); integerPrinter.print(); // 单独定义具体的类实现String打印 StringPrinter stringPrinter = new StringPrinter("Hello"); stringPrinter.print(); // 单独定义方法实现String打印 printString("Hello"); // 单独定义方法实现Integer打印 printInteger(100); } /** * 测试打印入口: * 使用了泛型之后,只需要定义一个方法,就可以同时打印字符串和数值, * 这样就可以解决代码冗余的问题,并且,如果需要打印其他类型,只需要定义一个方法即可,不需要再定义其他方法, * */ @Test public void testGenericsPrint() { // 只要定义一个类实现,接受一个泛型T,通过传递的T的类型,就可以实现打印不同类型的数据 GenericsPrinter<String> stringGenericsPrinter = new GenericsPrinter<>("Hello"); stringGenericsPrinter.print(); GenericsPrinter<Integer> integerGenericsPrinter = new GenericsPrinter<>(123); integerGenericsPrinter.print(); // 只要定义一个方法实现,接受一个泛型T,通过传递的T的类型,就可以实现打印不同类型的数据 printGenerics("Hello"); printGenerics(123); // 使用通配符后,List中的数据类型可以不受限制,可以灵活处理,只要符合通配符的范围即可。 List<Integer> integers = new ArrayList<>(); integers.add(123); integers.add(456); printGenerics(integers); List<String> string = new ArrayList<>(); string.add("123"); string.add("456"); printGenerics(string); // 这里直接会报错,因为已经限制了GenericsPrinter1传入的泛型T为Number的子类或者本身 // GenericsPrinter1<String> stringGenericsPrinter1 = new GenericsPrinter1<>(); // 这里直接会报错,因为已经限制了GenericsPrinter2传入的泛型T为Number的子类或者本身并且必须是实现了Serializable的子类 // GenericsPrinter2<String> stringGenericsPrinter2 = new GenericsPrinter2<>(); // 第一个参数传入的泛型T必须为Number的子类或者本身并且必须是实现了Serializable的子类 // 第二个参数传入的泛型K没有限制,可以传递String类型也可以传递Integer GenericsPrinter3<Integer, String> stringGenericsPrinter3 = new GenericsPrinter3<>(123, "hello word"); stringGenericsPrinter3.print(); } /** * 打印数值 * * @param integer 打印数值内容 */ private void printInteger(Integer integer) { System.out.println("Integer: " + integer); } /** * 打印字符串 * * @param string 打印字符串内容 */ private void printString(String string) { System.out.println("String: " + string); } /** * 打印内容:因为T在JAVA中并不是一个类型,只是一个占位符, * 那么需要明确告诉JAVA这里的T是一个泛型,才能正常编译通过, * 做法是在方法的返回值前边加上<T>。 * * @param context 打印内容,这里的T也可以是任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型, * 并且可以使用extend来进行限制类型。参考GenericsPrinter3的使用 */ private <T> void printGenerics(T context) { System.out.println("context: " + context); } /** * 打印内容:如果要打印这种List的情况,但是又不想限制List的类型,那么就使用 * 通配符<?>来表示,这样就可以打印List中的任意类型了。 * * @param context 打印内容,使用通配符<?>来表示,这样就可以打印List中的任意类型了, * 通配符也可以使用extend和super来表示范围,如: * <? extends Number>表示泛型为Number或Number子类的类型, * <? super Number>表示泛型为Number或Number父类的类型 */ private void printGenerics(List<?> context) { System.out.println("context: " + context); }
}
1.2、StringPrinter.java
/** * StringPrinter:专门用于打印字符串的类 */
public class StringPrinter { String string; public StringPrinter(String string) { this.string = string; } public void print() { System.out.println(string); }
}
1.3、IntegerPrinter.java
/** * IntegerPrinter:专门用于打印整数的类 */
public class IntegerPrinter { Integer integer; public IntegerPrinter(Integer integer) { this.integer = integer; } public void print() { System.out.println(integer); }
}
1.4、GenericsPrinter.java
/** * 泛型类:泛型类就是将泛型定义在类上,泛型类的类型参数只能被使用在类和接口中 * * @param <T> 泛型 */
public class GenericsPrinter<T> { T context; public GenericsPrinter(T context) { this.context = context; } public void print() { System.out.println(context); }
} /** * 有界限的泛型:限制传入的泛型类型必须继承自Number类 * * @param <T> 泛型 */
class GenericsPrinter1<T extends Number> { T context; public GenericsPrinter1(T context) { this.context = context; } public void print() { System.out.println(context); }
} /** * 有界限的泛型:限制传入的泛型类型必须继承自Number类和Serializable类 * 注意:Number & Serializable顺序不能错,因为不管泛型参数是抽象类还是接口都必须使用extends关键字, * 否则编译器会报错,由于JAVA的单一继承性,抽象类必须在前边且只有一个,使用&连接多个接口。 * * @param <T> 泛型 */
class GenericsPrinter2<T extends Number & Serializable> { T context; public GenericsPrinter2(T context) { this.context = context; } public void print() { System.out.println(context); }
} /** * 有界限的泛型:可以传递多个泛型参数, * 注意:Number & Serializable顺序不能错,因为不管泛型参数是抽象类还是接口都必须使用extends关键字, * 否则编译器会报错,由于JAVA的单一继承性,抽象类必须在前边且只有一个,使用&连接多个接口。 * * @param <T> 泛型,限制传入的泛型类型必须继承自Number类和Serializable类 * @param <K> 泛型,无限制 */
class GenericsPrinter3<T extends Number & Serializable, K> { T context; K context1; public GenericsPrinter3(T context, K context1) { this.context = context; this.context1 = context1; } public void print() { System.out.println(context.intValue()); System.out.println(context); System.out.println(context1); }
}相关文章:
JAVA中的泛型
一、泛型的概念 泛型是JAVA中的一个重要的概念,它允许你在编译时指定数据类型,从而使得代码更加灵活,更加通用。通过泛型,你可以在通用代码上操作不同数据类型,使得代码更加具有通用性。 二、泛型的使用场景 1、泛型…...
日撸代码300行:第73天(固定激活函数的BP神经网络,训练与测试过程理解)
进一步梳理理解了一下正向和反向传播。Forward 是利用当前网络对一条数据进行预测的过程,BackPropagation 是根据误差进行网络权重调节的过程。 完整的代码在72天,这里只粘贴Forward和BackPropagation两个方法。 /*** *********************************…...
css中常用单位辨析
辨析 px:像素;css中最普遍最常用的单位,不管在何种设备或分辨率上,1px始终代表屏幕上的一个像素。 %:百分比;基于父元素相对属性的百分比。 em:当前字体大小的倍数;基于父元素字体…...
Unity 一些常用特性收集
常用的类的特性 特性效果[Serializable]可序列化,作为一个子属性显示在Inspector面板[RequireComponent(typeof(CoomponnetName))]该类挂载的游戏物体,需要要有对应的组件[DisallowMultipleComponent]不允许挂载多个该类或其子类[ExecuteInEditMode]允许…...
select实现服务器并发
select的TCP服务器代码 #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/select.h> #include…...
【Spring底层原理】BeanFactory的实现
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 容器实现 一、BeanFactory实现的特点1.1 Be…...
c++---I/o操作
5、文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放。 我们可以通过文件将数据持久化 C中对文件操作需要包含头文件 <fstream> 文件类型分为两种: 文本文件 - 文件以文本的ASCII码形式存储在计算机中二进制文件 - 文…...
UG\NX二次开发 用程序修改“用户默认设置”
文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 简介 可以用程序修改“用户默认设置”吗?下面是用代码修改“用户默认设置->基本环境->用户界面->操作记录->操作记录语言”的例子。 效果 代码 #include <uf_defs.h> #include <NXOpen/NXExcept…...
什么是信号处理?如何处理信号?
C语言信号处理详解 第一部分:什么是信号? 信号是一种进程间通信的机制,用于通知进程发生了某种事件或异常情况。在C语言中,信号是一种软件中断,它可以被操作系统或其他进程发送给目标进程。每个信号都有一个唯一的数…...
谈谈 Redis 数据类型底层的数据结构?
谈谈 Redis 数据类型底层的数据结构? RedisObject 在 Redis 中,redisObject 是一个非常重要的数据结构,它用于保存字符串、列表、集合、哈希表和有序集合等类型的值。以下是关于 redisObject 结构体的定义: typedef struct redisObject {…...
九、GC收集日志
JVM由浅入深系列一、关于Java性能的误解二、Java性能概述三、了解JVM概述四、探索JVM架构五、垃圾收集基础六、HotSpot中的垃圾收集七、垃圾收集中级八、垃圾收集高级👋GC收集日志 ⚽️1. 认识GC收集日志 垃圾收集日志是一个重要的信息来源,对于与性能相关的一些悬而未决的…...
SimpleCG动画示例--汉诺塔动画演示
前言 SimpleCG的使用方法在前面已经介绍了许多,有兴趣的同学如果有去动手,制作一些简单动画应该没多大问题的。所以这次我们来演示一下简单动画。我们刚学习C语言的递归函数时,有一个经典例子相信很多同学都写过,那就是汉诺塔。那…...
反弹shell脚本(php-reverse-shell)
平时经常打靶机 这里贴一个 反弹shell的脚本 <?php // php-reverse-shell - A Reverse Shell implementation in PHP // Copyright (C) 2007 pentestmonkeypentestmonkey.net // // This tool may be used for legal purposes only. Users take full responsibility // f…...
XSS-labs
XSS常见的触发标签_xss标签_H3rmesk1t的博客-CSDN博客 该补习补习xss漏洞了 漏洞原理 网站存在 静态 和 动态 网站 xss 针对的网站 就是 动态网站 动态网站会根据 用户的环境 与 需求 反馈出 不同的响应静态页面 代码写死了 只会存在代码中有的内容 通过动态网站 用户体…...
C++简单实现AVL树
目录 一、AVL树的概念 二、AVL树的性质 三、AVL树节点的定义 四、AVL树的插入 4.1 parent的平衡因子为0 4.2 parent的平衡因子为1或-1 4.3 parent的平衡因子为2或-2 4.3.1 左单旋 4.3.2 右单旋 4.3.3 先左单旋再右单旋 4.3.4 先右单旋再左单旋 4.4 插入节点完整代码…...
UE4 Cesium 与ultra dynamic sky插件天气融合
晴天: 雨天: 雨天湿度: 小雪: 中雪: 找到该路径这个材质: 双击点开: 将Wet_Weather_Effects与Snow_Weather_Effects复制下来,包括参数节点 找到该路径这个材质,双击点开&…...
SpringCloud Gateway--Predicate/断言(详细介绍)下
😀前言 本篇博文是关于SpringCloud Gateway–Predicate/断言(详细介绍)下,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以…...
SOC芯片学习--GPIO简介
原创 硬件设计技术 硬件设计技术 2023-07-20 00:04 发表于广东 收录于合集#集成电路--IC7个 一、GPIO定义、分类: GPIO(英语:General-purpose input/output),通用型之输入输出的简称,其接脚可以供使用者由…...
skywalking源码本地编译运行经验总结
前言 最近工作原因在弄skywalking,为了进一步熟悉拉了代码下来准备debug,但是编译启动项目我就费了老大劲了,所以准备写这篇,帮兄弟们少踩点坑。 正确步骤 既然是用开源的东西,那么最好就是按照人家的方式使用&…...
K8s架构简述
以部署一个nginx服务说明kubernetes系统各个组件调用关系: 一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中 一个nginx服务的安装请求会首先被发送到master节点的apiServer组件 apiServer组件会调用scheduler组件来决定到底…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
