java9-泛型
1.泛型的简介
1.1 什么是泛型
泛型是一种特殊的数据类型。 它是Java 的一个高级特性。在 Mybatis、Hibernate 这种持久化框架,泛型更是无处不在。
在这之前,不管我们在定义成员变量时,还是方法的形参时,都要规定他们的具体类型。所以提出猜想,有没有一种可能,一次声明,就可以给各种各样的值呢?所以,泛型这个概念就出来了。
泛型的定义:
我们在定义一个语法结构时,不用指明具体类型,而是先定义一个类型变量,在真正使用的时候再确定该变量的具体类型。
总结: 类型参数化
两个参数化:
数据参数化: 就是使用形参接收具体数据(实际参数)
类型参数化: 就是使用形参接收具体类型。
1.2 泛型的定义
泛型,定义在一对尖括号中,也是一个标识符,遵循大驼峰命名法。通常都是用一个大写字母。
public class Test1<T> {
}
class Person<T,M>{
}
class Calculate<T>{public T calculate(T a, T b){return a;}
}
2.泛型的应用
2.1 泛型类的应用
当我们将泛型用在类上时,这个类就叫做泛型类。
泛型类: 泛型应用在类上。一般在类名后,使用尖括号括起来。用大写字母作为泛型参数。
演示代码:
import java.util.Date;public class Person<T> {private T idCard;public Person(){}public Person(T idCard){this.idCard = idCard;}public static void main(String[] args) {//创建一个Person对象。需要给泛型参数赋值具体类型Person p = new Person<String>("cds123");Person<String> p2 = new Person<>("cds122");// 泛型参数,只能赋值引用类型,不能赋值八大基本数据类型Person<Long> p3 = new Person<>(3215466L);Date date = new Date();//小贴士: 实例化过程中,泛型只在一边给泛型参数赋值,但是两遍的尖括号都不能省略。Person<Date> p4 = new Person<>(date);}
}/*
当一个子类继承带有泛型的父类时,一般情况下要给泛型参数赋值具体类名*/class Student extends Person<Integer>{public Student(Integer idCard){super(idCard);}
}
/*
子类的泛型参数可以给父类的泛型参数赋值。
下面的例子就是E赋值给了T。*/class Teacher<E> extends Person<E>{public Teacher(E idCard){super(idCard);}
}/*
如果子类在定义期间,没有给泛型父类的泛型参数赋值,那么默认就是Object类型*/
class Persident extends Person{public Persident(Object idCard){super(idCard);}}
总结:
在实例化时,要给泛型参数赋具体值。实例化时两边的类名都可以赋值,也可以一边赋值,但是两边的尖括号不能去掉。在继承时也要赋值,如果没有赋值,那就默认object类型。也可以将子类的泛型赋值给父类。
2.2 泛型接口的应用
将泛型用在接口上时,这个接口就叫做泛型接口。 泛型定义在接口名后。 用法和泛型类,一模一样。
测试代码:
import java.util.Arrays;
import java.util.Comparator;/*** 泛型接口,泛型用在接口上,就叫泛型接口。* @param <T>*/
public interface MyComparable<T,M> {/*** 两种类型进行比较* @param o1* @param o2* @return*/public int mycompare(T o1, M o2);public static void main(String[] args) {Employee[] employees = new Employee[3];employees[0] = new Employee("佐伊",18);employees[1] = new Employee("建模",19);employees[2] = new Employee("ez",17);//使用比较器接口,来重新定义比较规则: 从泛型的角度来说,在实例化接口时,要给泛型参数传具体类型。Comparator c = new Comparator<Employee>(){//重写比较器里面的compare方法public int compare(Employee o1, Employee o2) {//调用了自定义的员工类里的比较方法。return o1.name.compareTo(o2.name);}};Arrays.sort(employees);System.out.println(Arrays.toString(employees));}}
//子类实现接口 : 通常子类要给泛型接口的泛型参数赋值具体类型名。
//下面案例,就是给T和M都赋值了Employee这个类型。
class Employee implements MyComparable<Employee,Employee>, Comparator<Employee> {String name;int age;public Employee(String name, int age) {this.name = name;this.age = age;}public String toString(){return "["+name+","+age+"]";}// 在我们自己定义的方法中来实现比较规则。public int mycompare(Employee o1, Employee o2) {return o1.age - o2.age;}@Overridepublic int compare(Employee o1, Employee o2) {return mycompare(o1,o2);}}
2.3 泛型方法的应用
泛型不仅能用在类和接口上,还可以用在方法上。 需要把泛型定义在返回值类型前面。
测试代码:
import java.util.Objects;public class MyUtil {public static <T> boolean equals(T t1,T t2){return t1.equals(t2);}public static void main(String[] args) {Cat cat = new Cat("咪咪");Cat cat1 = new Cat("咪咪");//泛型方法在调用期间,不需要指定具体类型,只需要传入具体对象//泛型方法调用期间,并没有给泛型参数赋值。下面的案例是c1给t1,c2给t2赋值,没有给T赋值。boolean a = MyUtil.equals(cat, cat1);System.out.println("equals"+a);}
}class Cat{String name;public Cat(){}public Cat(String name){this.name = name;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Cat cat = (Cat) o;return Objects.equals(name, cat.name);}@Overridepublic int hashCode() {return Objects.hashCode(name);}
}
注意:
在方法调用期间,不需要给泛型具体赋值,只需要传入变量即可。
3.泛型通配符
3.1 简介
泛型通配符用 ? 表示,代表不确定的类型,是泛型的一个重要组成。 在调用时,表示我不关心具体类型。也可以使用通配符规定调用时,传入的类型的范围,即上边界,和下边界。
3.2 简单应用
import java.util.ArrayList;
import java.util.List;/*泛型通配符: ? 用于表明不关心调用时的具体类型。*/public class MyUtil {/*** 将集合元素打印到控制台上*/public static void print(List<?> lists){for(int i = 0; i<lists.size();i++){System.out.println(lists.get(i));}}/*** 上边界的定义: <? extends Number>* 具体使用的时候,可以是上边界的任何子类型或者是本类型。* @param list*/public static void print2(List<? extends Number> list){}/*** 下边界的定义: <? super 具体类名>* 具体使用的时候,可以是下边界的任何父类型或者本类型。* @param list*/public static void print3(List<? super Integer> list){for(int i = 0; i<list.size();i++){System.out.println(list.get(i));}}public static void main(String[] args) {List<Long> ns = new ArrayList<Long>();ns.add(1L);ns.add(2L);//注意 L 是Long类型不是long。ns.add(3L);MyUtil.print(ns);print2(new ArrayList<Long>());print2(new ArrayList<Number>());
// print2(new ArrayList<Object>());最高到达Number类型//下边界的测试print3(new ArrayList<Number>());print3(new ArrayList<Object>());print3(new ArrayList<Integer>());
// print3(new ArrayList<Long>());//Long和Integer没有关系。}}
3.3 总结
泛型是一种特殊的类型,你可以把泛型用在类、接口、方法上,从而实现一些通用算法。
此外,使用泛型有三个步骤:定义类型变量、使用类型变量、确定类型变量。
在确定类型变量这一步中,你可以用泛型通配符来限制泛型的范围,从而实现一些特殊算法。(方法 <? extends 类名>上边界、 <? super 类名>下边界(都包括类名))。
相关文章:
java9-泛型
1.泛型的简介 1.1 什么是泛型 泛型是一种特殊的数据类型。 它是Java 的一个高级特性。在 Mybatis、Hibernate 这种持久化框架,泛型更是无处不在。 在这之前,不管我们在定义成员变量时,还是方法的形参时,都要规定他们的具体类型…...
zotero安装与使用
文献管理工具) Zotero软件官网https://www.zotero.org/download,不修改安装位置,默认安装就行;安装完成官网直接邮箱注册一个账号,软件登陆账号:编辑-首选项-同步 修改论文保存位置,有从其它电脑拷贝过来的…...
Elasticsearch未授权访问漏洞
7.Elasticsearch未授权访问漏洞 Elasticsearch服务普遍存在一个未授权访问的问题,攻击者通常可以请求一个开放9200或9300的服务器进行恶意攻击。 步骤一:使用以下Fofa语法进行Elasticsearch产品搜索 "Elasticsearch" && port"9200" …...
【FPGA】module中CLOCK RESET iCall oDone的含义
一般的module并不只有iData和oData,还有其他的控制信号,如CLOCK RESET iCall oDone 基本的模式为 module cordicSinhCosh (input CLOCK,RESET,input iCall, output oDone,input [31:0]iData, output [31:0]oData, );reg [31:0] x;initial begin x = ...endreg signed [31:…...
OpenGL实现3D游戏编程【连载2】——了解并创建3D空间模型
1、本节实现的内容 上一节我们创建一个简单的窗口,本节我们需要了解一下细节内容,同时为了方便观看,我们需要显示一个世界坐标轴,建立一个直观的三维空间。 2、我们的眼睛设定(gluPerspective函数) 上一…...
Java-文件操作和IO
文件介绍 文件本身有多重含义,狭义的文件,特指硬盘上的文件(以及保存文件的目录),广义的文件:计算机上的很多硬件设备,软件资源,在操作系统中,都会被视为是"文件" 文件除了有数据内容之外,还有一部分信息,例如文件名,文件类型,文件大小,这些信息可以称作文件的元信…...
AI智能化赋能电商经济,守护消费净土,基于轻量级YOLOv8n开发构建公共生活景下的超大规模500余种商品商标logo智能化检测识别分析系统
在数字经济浪潮的推动下,全力发展新质生产力已成为当今社会发展的主旋律。各行各业正经历着前所未有的变革,其中,电商行业作为互联网经济的重要组成部分,更是以惊人的速度重塑着商业格局与消费模式。AI智能化技术的深度融合&#…...
C语言菜鸟入门·数据结构·链表超详细解析
目录 1. 单链表 1.1 什么是单链表 1.1.1 不带头节点的单链表 1.1.2 带头结点的单链表 1.2 单链表的插入 1.2.1 按位序插入 (1)带头结点 (2)不带头结点 1.2.2 指定结点的后插操作 1.2.3 指定结点的前插操作 1.3 …...
C# Unity 面向对象补全计划 七大原则 之 依赖倒置原则 (DIP)难度:☆☆ 总结:多抽象,多接口,少耦合
本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正 本系列作为七大原则和设计模式的进阶知识,看不懂没关系 请看专栏:http://t.csdnimg.cn/mIitr,查漏补缺 1.依赖倒置原则 (DIP) 这…...
大模型面试问题
综合基础 1、讲讲制作一个LLM的流程以及各阶段的作用 2、发现模型性能不好,如何从各个阶段去排查问题 查看各阶段中是否有对应训练数据,然后再向下排查。预训练 1、Transfomer模型介绍一下 2、讲讲 Q、K、V 3、Transfomer模型中Encoder输出给Decoder的…...
keeplive配置详解与haproxy配置详解
一、keepalive相关知识 1.1 keepalive介绍 keepalive即LVS集群当中的高可用架构,只是针对调度器的高可用。是高可用的HA架构。 keepalive就是基于VRRP协议来实现LVS高可用的方案。 1、组播地址 224.0.0.18,根据组播地址进行通信,主备之间发…...
vivado里的LUT、LUTRAM、FF、BRAM、DSP、IO、BUFG、MMCM资源介绍
vivado里的LUT、LUTRAM、FF、BRAM、DSP、IO、BUFG、MMCM资源介绍 提示:以下是本篇文章正文内容,写文章实属不易,希望能帮助到各位,转载请附上链接。 vivado实现电路用到的资源类型 LUT(Look-Up Table)&am…...
window关闭端口占用
文章目录 一、打开命令行,输入命令,得到进程号二、找到其端口并杀死该端口总结 一、打开命令行,输入命令,得到进程号 winr打开命令行,输入命令 netstat -ano | findstr 端口号得到端口号 二、找到其端口并杀死该端…...
Java:类和对象
类和对象 类(Class)类的定义 对象(Object)对象的创建 构造方法(Constructor)构造方法的定义 继承(Inheritance)继承的示例 总结示例一设想一个场景:创建一个虚拟动物园一…...
Pandas数据分析案例之用户购买记录分析
文章目录 数据分析之用户购买记录分析第一部分:数据类型处理数据加载观察数据查看数据的数据类型数据中是否存储在缺失值将order_dt转换成时间类型查看数据的统计描述计算所有用户购买商品的平均数量计算所有用户购买商品的平均花费 在源数据中添加一列表示月份:ast…...
串口调试可能遇见的常见问题和排查方法
串口UART作为嵌入式应用和通讯领域中最常用的接口之一,接口协议虽然简单,但在实际应 用中不同设备之间的通讯也会存在各种小问题,下面对使用中各种常见的问题做下总结和梳 理,可作为调试参考。 01串口通信常见问题 串口通信乱码…...
运放学习提纲
目的:给初入硬件的朋友一个系统性学习运放的参考方向,避免像无头苍蝇那般 一:偏置电流 1.1. 为什么是输入偏置电流? 1.2. 什么是输入偏置电流? 1.3. 怎么搜索资料?怎么把 ADI 模型导 入Multisim &#…...
nvidia系列教程-AGX-Orin系统刷机及备份
目录 前言 一、准备工作 二、AGX Orin 系统刷机步骤 三、AGX Orin 系统备份 总结 前言 NVIDIA AGX Orin 是一款高性能的嵌入式计算平台,专为边缘计算和 AI 应用而设计。为了确保系统的稳定性和适应不同的应用场景,用户可能需要对 AGX Orin 进行系统刷…...
将 Mojo 与 Python 结合使用
Mojo 允许您访问整个 Python 生态系统,但环境可能会因 Python 的安装方式而异。花些时间准确了解 Python 中的模块和包的工作原理是值得的,因为有一些复杂情况需要注意。如果您以前在调用 Python 代码时遇到困难,这将帮助您入门。 Python 中的模块和包 让我们从 Python 开始…...
Unrecognized option: --add-opens=java.base/java.lang=ALL-UNNAMED
Unrecognized option: --add-opensjava.base/java.langALL-UNNAMED Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. Disconnected from server 报错原因:这里我是启动一个SpringBoot项目的时候报这…...
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…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
