Java之泛型
文章目录
- 首先接着上一篇(集合)文章,来个非常牛逼的易错题
- 传统集合问题分析
- 泛型快速入门案例
- 泛型介绍
- 泛型的好处
- 泛型的语法
- 泛型的声明
- 泛型的实例化
- 泛型使用举例
- 泛型使用的注意事项和细节
- 自定义泛型
- 自定义泛型方法
- 自定义泛型接口
- 自定义泛型方法
- 泛型的继承和通配符
- JUnit
温馨提示,师从韩顺平
首先接着上一篇(集合)文章,来个非常牛逼的易错题
传统集合问题分析
泛型快速入门案例
package 泛型;import 集合.Set.Dog;import java.util.ArrayList;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo01 {public static void main(String[] args) {//使用传统的方法来解决===> 使用泛型
//老韩解读
//1. 当我们 ArrayList<Dog> 表示存放到 ArrayList 集合中的元素是 Dog 类型 (细节后面说...)
//2. 如果编译器发现添加的类型,不满足要求,就会报错
//3. 在遍历的时候,可以直接取出 Dog 类型而不是 Object
//4. public class ArrayList<E> {} E 称为泛型,那么 Dog->EArrayList<Dog> arrayList = new ArrayList<Dog>();arrayList.add(new Dog("旺财", 10));arrayList.add(new Dog("发财", 1));arrayList.add(new Dog("小黄", 5));
//假如我们的程序员,不小心,添加了一只猫
//arrayList.add(new Cat("招财猫", 8));System.out.println("===使用泛型====");for (Dog dog : arrayList) {System.out.println(dog.getName() + "-" + dog.getAge());}}
}
泛型介绍
package 泛型;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo01 {public static void main(String[] args) {Person<String> stringPerson = new Person<String>("小韩很牛逼!");stringPerson.showType(); //class java.lang.StringPerson<Integer> integerPerson = new Person<Integer>(100);integerPerson.showType(); //class java.lang.Integer}
}
//泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型
//或者是某个方法的返回值类型,或者是参数类型
class Person<E>{E s;public Person(E s) {this.s = s;}public E getS() {return s;}public void setS(E s) {this.s = s;}public void showType() {System.out.println(s.getClass()); //输出s的运行类型}
}
泛型的好处
泛型的语法
泛型的声明
泛型的实例化
泛型使用举例
package 泛型;import java.util.HashMap;
import java.util.Map;
import java.util.Set;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo02 {public static void main(String[] args) {Student student1 = new Student("小韩");Student student2 = new Student("小画");HashMap<String, Student> kvHashMap = new HashMap<String, Student>();/*public class HashMap<K,V>{}*/kvHashMap.put("小韩",student1);kvHashMap.put("小画",student2);System.out.println(kvHashMap);//第一种遍历方式Set<String> strings = kvHashMap.keySet();for (String key : strings) {System.out.println(kvHashMap.get(key));}//第二种遍历方式/*public Set<Map.Entry<K,V>> entrySet() {Set<Map.Entry<K,V>> es;return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;}*/Set<Map.Entry<String, Student>> entries = kvHashMap.entrySet();for (Map.Entry<String, Student> entry : entries) {System.out.println(entry.getKey()+":"+entry.getValue());}}
}
class Student{String name;public Student(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +'}';}
}
泛型使用的注意事项和细节
package 泛型;import java.util.ArrayList;
import java.util.List;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo03 {public static void main(String[] args) {
// 1. 泛型指向数据类型是引用类型,不能是基本数据类型ArrayList<Integer> integers = new ArrayList<Integer>();
//2. ArrayList<int> ints = new ArrayList<int>();Pig<A> as = new Pig<A>(new A());as.f(); //class 泛型.APig<A> bs = new Pig<A>(new B());bs.f(); //class 泛型.B
//3. 泛型的使用形式ArrayList<Integer> integers1 = new ArrayList<Integer>();List<Integer> integers2 = new ArrayList<Integer>();//在实际开发中,我们往往简写ArrayList<Integer> integers3 = new ArrayList<>();
//4. 如果这样写,泛型默认是ObjectArrayList list = new ArrayList();
// 等价于 ArrayList<Object> objects = new ArrayList<>();Tiger tiger = new Tiger();
// 等价于Tiger类的E为Object}
}
class A{}
class B extends A{}
class Pig<E>{E e;public Pig() {}public Pig(E e) {this.e = e;}public void f(){System.out.println(e.getClass());}}class Tiger<E>{E e;public Tiger() {}public Tiger(E e) {this.e = e;}
}
自定义泛型
自定义泛型方法
package 泛型;import java.util.Arrays;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo05 {public static void main(String[] args) {//T=Double, R=String, M=IntegerTige<Double,String,Integer> g = new Tige<>("john");g.setT(10.9); //OK
//g.setT("yy"); //错误,类型不对 T=DoubleSystem.out.println(g); //Tiger{name='john', r=null, m=null, t=10.9, ts=null}Tige g2 = new Tige("john~~");//OK T=Object R=Object M=Objectg2.setT("yy"); //OK ,因为 T=Object "yy"=String 是 Object 子类System.out.println("g2=" + g2);//g2=Tiger{name='john~~', r=null, m=null, t=yy, ts=null}}
}
//老韩解读
//1. Tiger 后面泛型,所以我们把 Tiger 就称为自定义泛型类
//2, T, R, M 泛型的标识符, 一般是单个大写字母
//3. 泛型标识符可以有多个.
//4. 普通成员可以使用泛型 (属性、方法)
//5. 使用泛型的数组,不能初始化
//6. 静态方法中不能使用类的泛型class Tige<T, R, M> {String name;R r; //属性使用到泛型M m;T t;//因为数组在 new 不能确定 T 的类型,就无法在内存开空间//不允许:T[] ts=new T[8];T[] ts;
//因为静态是和类相关的,在类加载时,对象还没有创建,泛型是在类定义的时候,才会被指定的
//所以,如果静态方法和静态属性使用了泛型,JVM 就无法完成初始化
// static R r2;
// public static void m1(M m) {
// }public Tige(String name) {this.name = name;}public Tige(R r, M m, T t) {//构造器使用泛型this.r = r;this.m = m;this.t = t;}public Tige(String name, R r, M m, T t) {//构造器使用泛型this.name = name;this.r = r;this.m = m;this.t = t;}//方法使用泛型public String getName() {return name;}public void setName(String name) {this.name = name;}public R getR() {return r;}public void setR(R r) {//方法使用到泛型this.r = r;}public M getM() {//返回类型可以使用泛型.return m;}public void setM(M m) {this.m = m;}public T getT() {return t;}public void setT(T t) {this.t = t;}@Overridepublic String toString() {return "Tiger{" +"name='" + name + '\'' +", r=" + r +", m=" + m +", t=" + t +", ts=" + Arrays.toString(ts) +'}';}
}
自定义泛型接口
package 泛型;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo06 {public static void main(String[] args) {}
}
/*泛型接口使用注意事项1. 接口中静态成员也不能使用泛型2. 泛型接口的类型,在继承接口或者实现接口时确定3. 没有指定类型默认为Object*/
interface IUSb<U,R>{int n = 10;//U name 不能 这样使用//普通方法中,可以使用接口泛型R get(U u);void hi(R r);void run(R r1 ,R r2, U u1,U u2);//在jdk8中,可以在接口中使用默认方法default R method(U u){return null;}
}//在实现接口时直接指定泛型接口的类型
class BB implements IUSb<Integer,Float>{@Overridepublic Float get(Integer integer) {return 0f;}@Overridepublic void hi(Float aFloat) {}@Overridepublic void run(Float r1, Float r2, Integer u1, Integer u2) {}
}
//在继承接口时,指定接口的类型
interface IA extends IUSb<String,Double>{}
//当我们去实现IA接口时,因为IA在继承IUSB接口时,指定了U为String R为Double
//因此在实现IUsu接口的方法时,使用Strin替换U,Double替换R
class AA implements IA{@Overridepublic Double get(String s) {return 0.0;}@Overridepublic void hi(Double aDouble) {}@Overridepublic void run(Double r1, Double r2, String u1, String u2) {}
}//等价于class CC implements IUSb<Object,Object>{}
class CC implements IUSb{@Overridepublic Object get(Object o) {return null;}@Overridepublic void hi(Object o) {}@Overridepublic void run(Object r1, Object r2, Object u1, Object u2) {}
}
自定义泛型方法
package 泛型;import java.util.ArrayList;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo07 {public static void main(String[] args) {Car car = new Car();car.fly("宝马",100); //当调用方法时,传入参数,编译器,就会确定类型//测试Fish<String, ArrayList> fish = new Fish<>();fish.hello(new ArrayList(),11.3);}
}
//泛型方法可以定义在普通类中,也可以定义在泛型类中
class Car{ //普通类public void run(){ } //普通方法public<T,R> void fly(T t,R r){ //泛型方法System.out.println(t.getClass()); //class java.lang.StringSystem.out.println(r.getClass()); //class java.lang.Integer}
}
class Fish<T,R> {//泛型类public void run(){ //普通方法}public<U,M> void eat(U u,M m){}//说明//1. 下面hi方法不是泛型类型//2. 是hi方法使用了类声明的泛型public void hi(T t){}//泛型方法,可以使用类声明的泛型,也可以使用自己声明的泛型public<K> void hello(R r,K k){System.out.println(r.getClass()); //class java.util.ArrayListSystem.out.println(k.getClass()); //class java.lang.Double}
}
泛型的继承和通配符
package 泛型;import java.util.ArrayList;
import java.util.List;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo08 {public static void main(String[] args) {//1. 泛型没有继承性// List<Object> list = new ArrayList<String>();//举例说明下列三个方法的使用List<Object> list1 = new ArrayList<>();List<String> list2 = new ArrayList<>();List<AAA> list3 = new ArrayList<>();List<BBB> list4 = new ArrayList<>();List<CCC> list5 = new ArrayList<>();//List<?>表示任意泛型类型都可以接受printCollection(list1);printCollection(list2);printCollection(list3);printCollection(list4);printCollection(list5);//?extends AAA 表示上限,可以接受 AAA 或者AAA类的父类,不限于直接子类// printCollection2(list1); // printCollection2(list2);printCollection2(list3);printCollection2(list4);printCollection2(list5);//super子类名 AAA :支持AAA类的父类,不限于直接父类printCollection3(list1);//printCollection3(list2);printCollection3(list3);//printCollection3(list4);//printCollection3(list5);}//List<?>表示任意泛型类型都可以接受public static void printCollection(List<?> c) {for(Object o : c) {System.out.println(o);}}//?extends AAA 表示上限,可以接受 AAA 或者AAA类的父类,不限于直接子类public static void printCollection2(List<? extends AAA> c) {for(Object o : c) {System.out.println(o);}}//super子类名 AAA :支持AAA类的父类,不限于直接父类public static void printCollection3(List<? super AAA> c) {for(Object o : c) {System.out.println(o);}}}
class AAA {
}
class BBB extends AAA {
}
class CCC extends BBB {
}
JUnit
- JUnit是一个Java语言的单元测试框架
- 多数Java的开发环境都已经集成了JUnit作为单元测试的工具
package 泛型;import org.junit.jupiter.api.Test;/*** @Author: 韩如意* @CreateTime: 2025-02-22* @Description: no* @Version: 1.0*/public class demo10 {public static void main(String[] args) {}@Testpublic void m1(){System.out.println("m1()方法被调用");}@Testpublic void m2(){System.out.println("m2()方法被调用");}
}
相关文章:

Java之泛型
文章目录 首先接着上一篇(集合)文章,来个非常牛逼的易错题传统集合问题分析泛型快速入门案例泛型介绍泛型的好处泛型的语法泛型的声明泛型的实例化泛型使用举例泛型使用的注意事项和细节 自定义泛型自定义泛型方法 自定义泛型接口自定义泛型方…...

图论 之 最小生成树
文章目录 题目1584.连接所有点的最小费用 最小生成树MST,有两种算法进行求解,分别是Kruskal算法和Prim算法Kruskal算法从边出发,适合用于稀疏图Prim算法从顶点出发,适合用于稠密图:基本思想是从一个起始顶点开始&#…...

STM32-有关内存堆栈、map文件
STM32堆栈空间大小设置_stm32堆栈分配大小-CSDN博客 STM32堆栈的大小及内存四(五)区的分析 - 天街小雨润地狠 - 博客园 .map文件的位置...
Linux系统中常见的词GNU是什么意思?
GNU 是 “GNU’s Not Unix” 的递归缩写,它是一个自由软件项目,旨在创建一个完全自由的操作系统。这个名字反映了GNU项目的核心理念:它试图创建一个类Unix的系统,但不是Unix本身。 GNU 项目由 理查德斯托曼(Richard S…...

【个人开源】——从零开始在高通手机上部署sd(二)
代码:https://github.com/chenjun2hao/qualcomm.ai 推理耗时统计 单位/ms 硬件qnncpu_clipqnncpu_unetqnncpu_vaehtp_cliphtp_unethtp_vae骁龙8 gen124716.994133440.39723.215411.097696.327 1. 下载依赖 下载opencv_x64.tar,提取码: rrbp下载opencv_aarch64.t…...
【MCU驱动开发概述】
MCU驱动开发概述 目录 MCU驱动开发概述二、驱动开发的目的三、驱动开发的关键组成部分四、示例 - LED 控制驱动 一、引言 MCU(Microcontroller Unit),即微控制器单元,是一种集成在单个芯片上的计算机系统,通常用于控制…...
PC端Linux之虚拟CAN
在调试QT程序时候需要用到虚拟CAN进行发送和接收的操作,以此记录方法。 在调试QT程序时候需要用到虚拟CAN进行发送和接收的操作,以此记录方法。 1、安装can-utils sudo apt install can-utils ifconig -a【查看是否安装成功,是否有can0网络…...
C++:std::thread、条件变量与信号量
介绍 在多线程编程的世界里,协调不同线程之间的工作是一项极具挑战性的任务。线程可能需要等待特定条件的满足,或者对共享资源的访问进行限制。C 标准库为我们提供了强大的工具,如 std::thread 用于创建和管理线程,条件变量用于线…...

POI pptx转图片
前言 ppt页面预览一直是个问题,office本身虽然有预览功能但是收费,一些开源的项目的预览又不太好用,例如开源的:kkfileview pptx转图片 1. 引入pom依赖 我这个项目比较老,使用版本较旧 <dependency><gro…...
Java File 类
File 类是 Java 中用于处理文件和目录的基本类之一,位于 java.io 包中。它提供了多种方法来创建、删除、检查、修改文件或目录的属性,以及列出文件夹中的内容。虽然 File 类本身不提供直接的读取或写入文件内容的方法(这些操作通常由 FileInp…...
工业通信协议 EtherNet/IP 全面解析
工业通信协议 EtherNet/IP 全面解析 EtherNet/IP(以太网工业协议)是一种基于标准以太网的工业自动化通信协议,由 ODVA(开放设备网供应商协会) 管理。它融合了 CIP(通用工业协议) 和以太网技术&…...

使用docker配置PostgreSQL
配置docker阿里云镜像仓库 国内使用docker hub拉取镜像比较慢,所以首先配置个人的镜像仓库。 阿里云的个人镜像仓库是免费的,对个人来说足够用。 具体操作参考阿里云官方链接 。 关于个人镜像仓库的使用参考链接。 配置完个人镜像仓库后将公网配置到doc…...

UITextView删除原有字符串时,光标会上移并且光标会变高
代码运行效果如图: import Foundationclass TestVC: UIViewController {override func viewDidLoad() {super.viewDidLoad()let testV MyCustomTextView(frame: CGRect(x: 0, y: 130, width: SCREEN_WIDTH - 50, height: 170))self.view.addSubview(testV)testV.ba…...

python入门 介绍及变量的使用
1.python介绍 python 是一门计算机语言 常见的计算机语言:python、java、C语言。。。 什么是计算机语言:就是让计算机知道你想干什么,把你的需求使用它能听懂的语言说出来 中国也有一门计算机语言:易语言 能认为是语言的本质上…...

51单片机-按键
1、独立按键 1.1、按键介绍 轻触开关是一种电子开关,使用时,轻轻按开关按钮就可使开关接通,当松开手时,开关断开。 1.2、独立按键原理 按键在闭合和断开时,触点会存在抖动现象。P2\P3\P1都是准双向IO口,…...
Java 8 至 Java 23 版本特性对比表
Java现在发布的版本很快,每年两个,但是真正会被大规模使用的是三年一个的TLS版本。 版本年份LTS关键特性影响力等级Java 82014✅Lambda 表达式、Stream API、方法引用、接口默认方法、Optional 类⭐⭐⭐⭐⭐Java 92017❌模块化系统(JPMS&…...

在wsl环境中配置和开发verilog(一种比较新颖的verilog开发指南)
WSL是windows中自带的linux子系统,笔者在若干月前首次接触其便爱不释手,verilog作为一种硬件解释语言,可否像c语言那样被游刃有余的编译和运行呢,笔者这次大胆的尝试在WSL环境VSCODEIverilog开发verilog。 首先默认按照了WSL和VS…...
AI学习指南HuggingFace篇-Hugging Face 的核心工具
一、引言 Hugging Face作为AI领域的重要参与者,提供了许多强大的工具,极大地简化了自然语言处理(NLP)任务的开发流程。其中,Transformers、Datasets 和 Tokenizers 是Hugging Face的三大核心工具。本文将深入介绍这些工具的作用、功能以及它们如何相互配合,帮助读者更好…...

DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...

QT 引入Quazip和Zlib源码工程到项目中,无需编译成库,跨平台,压缩进度
前言 最近在做项目时遇到一个需求,需要将升级的文件压缩成zip,再进行传输; 通过网络调研,有许多方式可以实现,例如QT私有模块的ZipReader、QZipWriter;或者第三方库zlib或者libzip或者quazip等࿱…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...