一篇文章搞定Java泛型

目录

介绍

优点

泛型类

语法定义

代码示例 

泛型类注意事项

 抽奖示例

 泛型类派生子类

定义

代码示例

子类是泛型

 子类不是泛型

 泛型接口

定义

泛型方法

定义

 代码示例

 泛型方法与可变参数

泛型方法总结 

​编辑类型通配符

定义 

 代码示例

通配符的上限 

定义

代码示例

通配符的下限 

定义

 代码示例

 jdk中下限通配符的使用

 类型擦除

泛型与数组 

泛型与反射 

定义

代码示例 


介绍

JAVA推出泛型以前,程序员可以构建一个元素类型为Object的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数据类型,否则很容易引发ClassCastException异常。

Java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许我们在编译时检测到非法的类型数据结构。

泛型的本质就是参数化类型,也就是所操作的数据类型被指定为一个参数。

优点

类型安全

消除了强制类型的转换

泛型类

语法定义

 

代码示例 

// <T> 泛型标识--类型形参  T创建对象的时候指定具体的数据类型
public class Generic<T> {//T 外部创建使用类的时候来指定  可以理解为 谁用谁定义private T key;public Generic() {}public Generic(T key) {this.key = key;}public T getKey() {return key;}public void setKey(T key) {this.key = key;}@Overridepublic String toString() {return "Generic{" +"key=" + key +'}';}
}

 测试:

 注意泛型类不支持基本数据类型 这点在编译时就会有报警提示

泛型类注意事项

 抽奖示例

public class ProdocGetter<T> {Random random = new Random();//奖品private T product;//奖品池List<T> list = new ArrayList<>();//添加奖品public void addPro(T t){list.add(t);}//随机抽奖public T getProduct(){return list.get(random.nextInt(list.size()));}public static void main(String[] args) {//创建抽奖器对象 指定奖品类型(数据类型)ProdocGetter<String> stringProdocGetter = new ProdocGetter<>();String[] strings = {"苹果电脑","小米手机","奔驰汽车","迪迦奥特曼玩具"};//奖品池塞入奖品for (String pro : strings) {stringProdocGetter.addPro(pro);}//抽奖System.out.println("恭喜您,抽中了:"+stringProdocGetter.getProduct());System.out.println("分割线====================================");ProdocGetter<Integer> intProdocGetter = new ProdocGetter<>();Integer[] integers = {100,500,9000,16645,30458};//奖品池塞入奖品for (Integer pro : integers) {intProdocGetter.addPro(pro);}//抽奖System.out.println("恭喜您,抽中了:"+intProdocGetter.getProduct()+"元");}
}

测试:

 泛型类派生子类

定义

代码示例

子类是泛型

父类泛型

public class Parent<E> {private E value;public E getValue() {return value;}public void setValue(E value) {this.value = value;}
}

 子类泛型

//泛型类派生子类,子类也是泛型类,那么子类的泛型标识要和父类一致。
public class Child<T> extends Parent<T>{@Overridepublic T getValue() {return super.getValue();}public static void main(String[] args) {Child<String> child = new Child<>();child.setValue("我是一个字符串");System.out.println(child.getValue());}
}

测试:

注意此时的子类泛型是T,继承的父类也是T,而最原先定义的父类泛型是E

子类如果是泛型,那么必须指定父类泛型和子类是一致的

如果不一致:

 子类不是泛型

//泛型类派生子类 如果子类不是泛型,那么父类需要明确指定数据类型 如果不指定那么数据类型则为Object
public class ChildSecond extends Parent<Integer>{@Overridepublic Integer getValue() {return super.getValue();}@Overridepublic void setValue(Integer value) {super.setValue(value);}public static void main(String[] args) {ChildSecond  childSecond = new ChildSecond();childSecond.setValue(1000);System.out.println(childSecond.getValue());}
}

测试:

 如果不明确指定父类的数据类型

 泛型接口

定义

 

 泛型接口的代码示例和泛型类派生子类如出一辙,不再代码示例

泛型方法

定义

 代码示例

 还是以之前的例子,但是这里需要多定义一个泛型方法

public class ProdocGetter<T> {Random random = new Random();//奖品private T product;//奖品池List<T> list = new ArrayList<>();//添加奖品public void addPro(T t){list.add(t);}//随机抽奖public T getProduct(){return list.get(random.nextInt(list.size()));}//定义泛型方法public <E> E getProduct(List<E> list){return list.get(random.nextInt(list.size()));}public static void main(String[] args) {ProdocGetter<Integer> prodocGetter = new ProdocGetter<>();List<String> strList = new ArrayList<>();strList.add("华为手机");strList.add("苹果手表");strList.add("空调");//泛型方法的调用 类型是通过调用方法的时候来指定String procut = prodocGetter.getProduct(strList);System.out.println(procut+"\t"+procut.getClass().getSimpleName());System.out.println("分割线=============================================>");ArrayList<Integer> integers = new  ArrayList<>();integers.add(100);integers.add(30004);integers.add(6471);Integer integer = prodocGetter.getProduct(integers);System.out.println(integer+"\t"+integer.getClass().getSimpleName());}
}

测试:

 定义多个泛型类型的静态泛型方法

 泛型方法与可变参数

 

泛型方法总结 

类型通配符

定义 

 代码示例

我们先看下数据类型Integer和Number的关系

点进Integer可以看到Integer是继承了Number

根据原先多态的想法,我们可以这样定义:

但是这里却报错了

也就是说泛型这里不可以使用多态来进一步转换类型数据,这个时候类型通配符的作用就显现出来了

通配符的上限 

定义

代码示例

书写三个继承关系类,Animal->BIgDog->Dog

Animal:

public class Animal {
}

 BIgDog:

public class BIgDog extends Animal{
}

Dog:

public class Dog extends BIgDog{
}

测试:

本次没有测试演示,可以看到此时定义的通配符上限类为BigDog,所以showAnimal中传递的集合数据类型只能由BigDog或者BigDog的子类,BigDog的父类Animal已经报警不可用

 

需要注意的是通配符上限的集合是不允许填充实例数据的,比如:

因为此时定义了通配符的上限类,而集合根本不确定集合中存的数据是什么数据类型

通配符的下限 

定义

 代码示例

 可以看到此时定义的通配符下限类为BigDog,所以showAnimals中传递的集合数据类型只能由BigDog或者BigDog的父类,BigDog的子类Dog已经报警不可用

通配符下限这里集合是可以直接添加实例的

 jdk中下限通配符的使用

改造三个类

Animal

public class Animal {public String name;public Animal(String name) {this.name = name;}@Overridepublic String toString() {return "Animal{" +"name='" + name + '\'' +'}';}
}

BigDog

public class BIgDog extends Animal{public Integer age;public BIgDog(String name, Integer age) {super(name);this.age = age;}@Overridepublic String toString() {return "BIgDog{" +"age=" + age +", name='" + name + '\'' +'}';}
}

Dog

public class Dog extends BIgDog{public Integer level;public Dog(String name, Integer age, Integer level) {super(name, age);this.level = level;}@Overridepublic String toString() {return "Dog{" +"level=" + level +", age=" + age +", name='" + name + '\'' +'}';}
}

TreeSet中的有一个构造函数就是典型的通配符下限使用

 测试:

 

 类型擦除

 

 

 

泛型与数组 

泛型与反射 

定义

代码示例 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

致敬图灵!HashData拥抱数据智能新时代!

图1&#xff1a;2023ACM中国图灵大会现场 生于1912年的艾伦图灵被称为“计算机科学之父”、“人工智能之父”。1966年&#xff0c;国际计算机协会&#xff08;ACM&#xff09;为了纪念这位卓越的科学家&#xff0c;设立了以其名字命名的ACM图灵奖&#xff0c;以表彰在计算机领…

入门redis你一定需要知道的命令

1、各种数据类型的特点 字符串(string)&#xff1a;普通字符串&#xff0c;Redis中最简单的数据类型 哈希(hash)&#xff1a;也叫散列&#xff0c;类似于Java中的HashMap结构 列表(list)&#xff1a;按照插入顺序排序&#xff0c;可以有重复元素&#xff0c;类似于Java中的Li…

nginx如何配置两个服务器的连接

nginx 中通过server_name listen的方式配置多个服务器 nginx配置两个站点的windows操作方法&#xff0c;双域名双站点

JavaWeb_LeadNews_Day4-阿里云内容安全, 雪花算法, app文章保存, 自媒体文章审核

JavaWeb_LeadNews_Day4-阿里云内容安全, 雪花算法, app文章保存, 自媒体文章审核 阿里云内容安全分布式主键策略-雪花算法app文章保存具体实现总结 自媒体文章审核提取内容和图片审核内容和图片保存app端文章Feign远程调用降级发布文章异步调用自管理敏感词图片文字识别入门集成…

【【51单片机11.0592晶振红外遥控】】

51单片机11.0592晶振红外遥控 红外遥控&#xff0c;51单片机完结 这是初步实现的架构 怎么实现内部的详细逻辑 我们用状态机的方法 0状态时一个空闲状态 当它接收到下降沿开始计时然后转为1状态 1状态下 寻找start 或者repeat的信号 再来下降沿读出定时器的值 如果是start 那…

UE4/5C++多线程插件制作(十八、Graph线程封装,以及宏的设置)

目录​​​​​​​ 什么是Graph线程? MTPThreadGraphManage.h MTPThreadInterface.h MTPThreadGraphManage.h MTPManage.cpp void FMTPThreadGraphManage::Wait(const FGraphEventRef& EventRef)</

QT 常用数据结构整理

目录 QString篇 QString篇 //初始化bool bOk false;QString str "sd";QString strTemp(str);str QString("%1,%2").arg("11").arg("-gg");qDebug()<<str;str.sprintf("%s %d","ni",1);qDebug()<<…

网安笔记2

一、实例对象 1.对象是单个实物的抽象&#xff0c;是一个容器&#xff0c;封装了属性和方法 2.构造函数&#xff0c;构造函数就是一个普通的函数&#xff0c;但具有自己的特征和用法。 var Vehicle function () { this.price 1000; }; 上面代码中&#xff0c;Ve…

前端(Electron Nodejs)如何读取本地配置文件

使用electron封装了前端界面之后&#xff0c;最终打包为一个客户端&#xff08;exe&#xff09;。但是&#xff0c;最近项目组内做CS&#xff08;c开发&#xff09;的&#xff0c;想把所有的配置都放进安装目录的配置文件中&#xff08;比如config.json&#xff09;。这做法&am…

M 芯片的 macos 系统安装虚拟机 centos7 网络配置

centos 安装之前把网络配置配好或者是把网线插好 第一步找到这个 第二步打开网络适配器 选择图中所指位置 设置好之后 开机启动 centos 第三步 开机以后 编写网卡文件保存 重启网卡就可以了&#xff0c;如果重启网卡不管用&#xff0c;则重启虚拟机即可 “ ifcfg-ens160 ” 这…

黑苹果如何在macOS Sonoma中驱动博通网卡

准备资源&#xff08;百度&#xff1a;黑果魏叔 下载&#xff09; 资源包中包含&#xff1a;AirportBrcmFixup.kext/IOSkywalkFamily.kext/IO80211FamilyLegacy.kext/OpenCore-Patcher 使用方法&#xff1a; 1.将 csr-active-config 设置为 03080000 全选代码 复制 2.在 …

c++数据锁链

题目描述&#xff1a; 创建一个结构体为Node&#xff0c;具有value , next 两个属性&#xff1b; value为整型&#xff0c;用来储存结构体数值&#xff1b; next为Node类型指针&#xff0c;用来指向下一组数据地址&#xff1b; 第1组数据value 5&#xff1b; 第2组数据value …

php查询数据(日期查询)和fastadmin的日期查询

当前月查询 要在 PHP 中查询数据库中当前月份的数据&#xff0c;需要使用 SQL 查询语句来筛选出符合条件的数据。首先&#xff0c;确保数据库中有一个日期或时间类型的字段用于存储记录的日期信息。 假设你的数据库表名为 my_table&#xff0c;其中有一个名为 date_column 的…

MATLAB RANSAC平面拟合 (29)

MATLAB RANSAC平面拟合 (29) 一、算法简介二、函数介绍三、算法实现四、效果展示一、算法简介 将一个平面与一个从内点到平面的最大允许距离的点云相匹配。该函数返回描述平面的几何模型。该函数采用 M- 估计量样本一致性(MSAC)算法求解平面。MSAC 算法是随机样本一致性(RAN…

【C++】STL——list的介绍和使用、list增删查改函数的介绍和使用、push_back、pop_back

文章目录 1.list的使用2.list的增删查改函数&#xff08;1&#xff09;push_front 在list首元素前插入值为val的元素&#xff08;2&#xff09;pop_front 删除list中第一个元素&#xff08;3&#xff09;push_back 在list尾部插入值为val的元素&#xff08;4&#xff09;pop_ba…

常用的一些蓝图(持续更新)

文章目录 ADEIPS A Apply Damage: 对指定的actor应用伤害。 Add Mapping Context: 添加控制映射上下文。 D Do Once: 仅在第一次命中节点时触发&#xff0c;但可以重置。 Delay: 延迟执行。 Destroy Actor: 销毁指定的actor。 E Enhanced Input Local Player Subsystem: 从玩家…

Elasticsearch 分片策略

文章目录 分片索引设置分片获取索引分片信息示例 分片分配集群级分片分配索引级分片分配索引级分片筛选每个节点的分片总数索引恢复优先级节点掉线时延时分配 分片 和数据库中的表空间类似&#xff0c;不过分片是为每个索引设置&#xff0c;一个索引可以有多个分片&#xff0c…

TCP三次握手/四次挥手

三次握手 三次握手过程 TCP服务器进程先创建传输控制块TCB&#xff0c;时刻准备接受客户进程的连接请求&#xff0c;此时服务器就进入了LISTEN&#xff08;监听&#xff09;状态&#xff1b;TCP客户进程也是先创建传输控制块TCB&#xff0c;然后向服务器发出连接请求报文&…

【QT 网络云盘客户端】——登录界面功能的实现

目录 1.注册账号 2.服务器ip地址和端口号设置 3. 登录功能 4.读取配置文件 5.显示主界面 1.注册账号 1.点击注册页面&#xff0c;将数据 输入 到 用户名&#xff0c;昵称&#xff0c;密码&#xff0c;确认密码&#xff0c;手机&#xff0c;邮箱 的输入框中&#xff0c; 点…

【C语言学习——————动态内存管理】

文章目录 一、什么是动态内存管理二、动态内存函数的介绍 1.malloc函数的介绍2.calloc函数的介绍3.realloc函数的介绍三、free函数的介绍 一.什么是动态内存管理 我们知道数据都是在内存中进行储存的&#xff0c;但是如果我们需要调用内存&#xff0c;我们可以通过定义一个变量…