Java中的泛型

泛型

  • 什么是泛型
    • 泛型类
    • 泛型接口
    • 泛型方法
      • 通配符
      • 泛型的上下限
  • 泛型的注意事项
    • 擦除问题
    • 基本数据类型问题

什么是泛型

定义类、接口、方法时,同时声明了一个或者多个类型变量(如:),称为泛型类、泛型接口,泛型方法、它们统称为泛型。

作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力。这样可以避免强制类型转换,及其可能出现的异常。

泛型的本质:把具体的数据类型作为参数传给类变量。

自定义泛型类
自定义泛型接口
自定义泛型方法

泛型类

在这里插入图片描述
eg. 模拟ArrayList类

//泛型类
//这里的E,使用A、B、C都是一样的,一般使用E、T、K、V
public class MyArrayList<E> {
	private Object[] arr = new Object[10];
	private int size; //记录当前位置的
	public boolean add(E e) {
		arr[size++] = e;
		return true;
	}
	public E get(int index) {
		return (E) arr[index];
	}
	
}
//泛型类
//这里的E,使用A、B、C都是一样的,一般使用E、T、K、V
public class MyClass<E, T> {
	public void put(E e, T t) {

	}
}
//泛型类3
//在使用时这里的E必须要是继承Animal类的类才可以放进来
//泛型类可以通过extends的方式来限制放入的类型变量
public class MyClass3<E extends Animal> {
	
}

public class Dog extends Animal {
}
//会报错,因为String类型没有继承Animal
MyClass3<String> c3 = new MyClass();
//正确,可以放入Animal本身
MyClass3<Animal> c3 = new MyClass();
//正确,因为Dog继承了animal
MyClass3<Dog> c3 = new MyClass();

泛型接口

在这里插入图片描述
eg.
场景:系统需要处理学生和老师的数据,需要提供2个功能:
保存对象数据,
根据名称查询数据。

//老师类
public class Teacher {
}
//学生类
public class Student {
}
//泛型接口
public interface Data<T> {
	void add(T t);
	ArrayList<T> getByName(String name);
}

//实现类
public class TeacherData implements Data<Teacher> {
	@Override
	public void add(Teacher teacher) {
	}
	@Override
	public ArrayList<Teacher> getByName(String name) {
		return null;
	}
}

//实现类
public class StudentData implements Data<Student> {
	@Override
	public void add(Student student) {
	}
	@Override
	public ArrayList<Student> getByName(String name) {
		return null;
	}
}

public class Test {
	public static void main(String[] args)
}

泛型方法

在这里插入图片描述
在这里插入图片描述

通配符

  • 就是“?“,可以在“使用泛型“的时候代表一切类型;E T K V 是在定义泛型的时候使用。

泛型的上下限

  • ? extends Car(上限) ?能接收的必须是Car或Car的子类
  • ? super Car(下限) ?能接收的必须是Car或Car的父类
public static <T> T test(T t) {
	return t;
}
//正确
test(new Dog());
test("java");

eg
需求: 所有的汽车可以一起参加比赛

public class Car {
}

public class BMW extends Car {
}

public class BENZ extends Car {
}

public static void go(ArrayList<Car> cars) {

}

ArrayList<Car> cars = new ArrayList<>();
cars.add(new BMw());
cars.add(new BENZ());
go (cars);

ArrayList<BMW> bmws = new ArrayList<>();
//加入两辆宝马车
bmws.add(new BMW());
bmws.add(new BMW());
//会报错,重点:Car是父类,但ArrayList的Car和ArrayList的BMW是没有关系的
go(bmws);

解决方法

//这样所有类型的ArrayList都可以送进来
public static <T> void go(ArrayList<T> cars) {
}
//仅限定汽车能进来
public static <T extends Car> void go(ArrayList<T> cars) {
}
//ArrayList本身就是泛型,?是通配符,在使用泛型时可以代表一切类型
public static void go(ArrayList<?> cars) {
}
//加入限定
// ? extends Car(上限) 必须是Car或Car的子类
// ? super Car(下限) 必须是Car或Car的父类
//此时可以送入的类型是Car以及Car的子类
public static void go(ArrayList<? extends Car> cars) {
}

泛型的注意事项

擦除问题

  • 泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型类,这就是泛型擦除

在这里插入图片描述
class底层中帮你强转类型

基本数据类型问题

  • 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)

引用类型都是Object的子类,而基本类型不是类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/320164.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

说说TCP 3次握⼿和4次握手

三次握手过程 client端建⽴连接&#xff0c;发送⼀个SYN同步包&#xff0c;发送之后状态变成SYN_SENTserver端收到SYN之后&#xff0c;同意建⽴连接&#xff0c;返回⼀个ACK响应&#xff0c;同时也会给client发送⼀个SYN包&#xff0c;发送完成之后状态变为SYN_RCVDclient端收到…

PySide6/PyQt6中的时间管理类:QTime的使用方法

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📝 创建QTime对象📝 常用方法⚓️ 相关链接 ⚓️📖 介绍 📖 QTime是PySide6中用于处理时间段的类,可以用来表示一天中的时间,例如小时、分钟和秒。它提供了许多操作和格式化时间的功能,使得处理时间变得更加…

MATLAB中simulink中scope同时显示两个输入信号

在使用scope时&#xff0c;需要两个输入信号的设置方法 1.点开scope图标 2 点击设置按钮&#xff0c; 然后弹出configuration properties&#xff1a;scope配置图&#xff0c;在Main选项下&#xff0c;在Number of input ports&#xff1a;1这里面更改数字&#xff0c;需要几…

vscode中如何解决 Comments are not permitted(JSON中不允许注释)

vs code中如何解决Comments are not permitted&#xff08;JSON中不允许注释&#xff09;&#xff1f; 简单几步&#xff0c;让你轻松解决。 1.使用vscode打开json文件后&#xff0c;一些注释显示如图所示&#xff0c;有红色波浪线&#xff0c;影响阅读 2. 悬浮在波浪线报错信…

【MySQL】mysql集群

文章目录 一、mysql日志错误日志查询日志二进制日志慢查询日志redo log和undo log 二、mysql集群主从复制原理介绍配置命令 读写分离原理介绍配置命令 三、mysql分库分表垂直拆分水平拆分 一、mysql日志 MySQL日志 是记录 MySQL 数据库系统运行过程中不同事件和操作的信息的文件…

RocketMQ源码阅读-Broker消息接收

RocketMQ源码阅读-Broker消息接收 1. 从单元测试入手2. Broker启动流程3. Broker接收消息4. Broker接收消息时序图5. 小结 Broker接收 Producer发送的消息。 Broker在RocketMQ中也是一个独立的Model&#xff0c;rocketmq-broker。 Broker的核心类为SendMessageProcessor。 …

opencv多张图片实现全景拼接

最近camera项目需要用到全景拼接&#xff0c;故此查阅大量资料&#xff0c;终于将此功能应用在实际项目上&#xff0c;下面总结一下此过程中遇到的一些问题及解决方式&#xff0c;同时也会将源码附在结尾处&#xff0c;供大家参考&#xff0c;本文采用的opencv版本为3.4.12。 首…

一天吃透JVM面试八股文

内容摘自我的学习网站&#xff1a;topjavaer.cn 什么是JVM&#xff1f; JVM&#xff0c;全称Java Virtual Machine&#xff08;Java虚拟机&#xff09;&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。由一套字节码指令集、一组寄存器、一个栈、一个垃圾回…

前端基础知识整理汇总(下)

react 生命周期 React v16.0前的生命周期 初始化(initialization)阶段 此阶段只有一个生命周期方法&#xff1a;constructor。 constructor() 用来做一些组件的初始化工作&#xff0c;如定义this.state的初始内容。如果不初始化 state 或不进行方法绑定&#xff0c;则不需…

Jenkins自动化部署docker

Jenkins自动化部署docker和普通方式构建 docker外挂目录 准备测试服务器docker环境准备jdk环境将上传jar包修改为app.jar对外暴露1000端口启动jar FROM openjdk:8-jdk-alpine ARG JAR_FILE COPY ${JAR_FILE} app.jar EXPOSE 1000 ENTRYPOINT ["java","-jar&q…

spring-boot2.7.8添加swagger

一、新建项目swaggerdemo 二、修改pom.xml 注意修改&#xff1a;spring-boot-starter-parent版本为&#xff1a;2.7.8 添加依赖&#xff1a; springfox-swagger2 springfox-swagger-ui springfox-boot-starter <?xml version"1.0" encoding"UTF-8"…

ruoyi后台管理系统部署-3-安装redis

centos7安装redis 1. yum 安装 查看是否安装了redis yum installed list | grep redis ps -ef | grep redis安装epel 仓库&#xff08;仓库是软件包下载的&#xff0c;类似maven&#xff0c;nuget&#xff09; yum install epel-release搜索 redis 包 yum search redis安装…

剪映国际版,免费无限制使用

随着抖音的爆火短视频的崛起&#xff0c;相信每一个人都感受到了短视频快节奏下的生活洪流。 现如今每个人都能成为自己生活的记录者&#xff0c;每一个人都有掌握着剪辑的基本技能。而剪映就是很多人都会使用的剪辑软件。 相对于PR、AE等剪辑软件来说&#xff0c;作为一款国…

动态规划篇-01:爬楼梯

本文为力扣70&#xff1a;爬楼梯的详细解析。 虽然这道题的标签是“简单”&#xff0c;但是只有简单的题才能让我们专注于这类题的解题框架上。 一般来说动态规划会有三种解法&#xff1a;暴力解法、使用了备忘录自上而下的递归解法、使用了数组的自下而上的迭代解法。接下来…

FineBI实战项目一(21):不同支付方式订单总额分析开发

点击新建组件&#xff0c;创建不同支付方式订单总额组件。 选择饼图&#xff0c;拖拽total_money到角度&#xff0c;拖拽pay_type到颜色&#xff0c;调节内径。 修改颜色的标识文字。 将组件拖拽到仪表板。 结果如下&#xff1a;

用C语言实现哈希表HashMap

代码仓库地址 1. 功能说明 自定义初始容量和负载因子&#xff1b;当键值对的个数与容量比值超过负载因子时&#xff0c;自动扩容&#xff1b;借鉴Java8的HashMap部分扩容逻辑&#xff0c;定义了单独的桶结构体用于记录hash值&#xff0c;以及2倍扩容&#xff0c;减少了hash运算…

K8S--service

一、简介 Service 是将集群中的 一个或一组 Pod应用程序公开为网络服务的方法。我们都知道pod是不稳定的,有可能时时刻刻都在创建和销毁,这一时刻运行的 Pod 集合可能不同于下一刻运行该应用的 Pod 集合,并且新创建的pod的ip地址会改变,所以我们不应该寄期望于pod的稳定性…

Calibre DESIGNrev Object Selection Toolbar

包括 Reference Path Polygon Edge Vertex Text的解释说明 FieldDescription用法&#xff08;勾选后&#xff09;ReferenceUsed to move or select a cell reference or array reference.可以选择一个cellPathUsed to move or select a contiguous path object.暂时不明请指教…

浏览器进程模型和JS的事件循环

一、浏览器的进程模型 1、什么是进程&#xff1f; 程序运行所需要的专属内存空间 2、什么是线程&#xff1f; ​​​​​运行​代码的称为线程&#xff08;同一个进程中的线程共享进程的资源&#xff09; ⼀个进程⾄少有⼀个线程&#xff0c;所以在进程开启后会⾃动创建⼀个线…

k8s云原生环境搭建笔记——第二篇

目录 1、使用普通方式安装prometheus和grafana1.1、安装kube-state-metrics容器1.1.1、下载并修改yaml文件1.1.2、导入kube-state-metrics镜像1.1.3、执行yaml文件目录 1.2、安装node-exploer1.2.1、创建名称空间prometheus1.2.2、执行yaml 1.3、安装prometheus1.3.1、创建集群…