一篇文章搞定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…

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

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

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 …

【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…

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;我们可以通过定义一个变量…

网络安全系统中的守护者:如何借助威胁情报 (TI) 提高安全性

在这篇哈巴尔网站上的推文中&#xff0c;我们将解释 TI 缩写背后的含义、为什么需要它、Positive Technologies 收集哪些网络威胁数据以及如何帮助企业预防网络威胁。我们将以四种情况为例&#xff0c;说明公司如何使用 PT Threat Intelligence Feeds 来发现恶意活动并预防攻击…

vue3+ts+elementui-plus二次封装树形表格

复制粘贴即可&#xff1a; 一、定义table组件 <template><div classmain><div><el-table ref"multipleTableRef" :height"height" :default-expand-all"isExpend" :data"treeTableData"style"width: 100%…

从官网认识 JDK,JRE,JVM 三者的关系

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM 是一些大厂面试必问点&#xff0c;要想解决 OOM、性能调优方面的问题&#xff0c;掌握 JVM 知识必不可少&#xff0c;从今天开始&#xff0c;将为大家介绍 JVM 的常用知…

【Docker】Docker应用部署之Docekr容器安装Nginx

目录 一、搜索镜像 二、拉取镜像 三、创建容器 四、测试使用 一、搜索镜像 docker search nginx 二、拉取镜像 docker pull nginx # 不加冒号版本号 默认拉取最新版 三、创建容器 首先我们需要在宿主机创建数据卷目录 mkdir nginx # 创建目录 cd nginx # 进入目录 mkd…

Verilog语法学习——LV9_使用子模块实现三输入数的大小比较

LV9_使用子模块实现三输入数的大小比较 题目来源于牛客网 [牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page1&tabVerilog篇&topicId301) 题目 描述 在数字芯片设计中&#xff0c;通常把完成特定功能且相对独立的…

LeetCode刷题总结 - 面试经典 150 题 -持续更新

LeetCode刷题总结 - 面试经典 150 题 - 持续更新 其他系列数组 / 字符串88. 合并两个有序数组27. 移除元素26. 删除有序数组中的重复项80. 删除有序数组中的重复项 II169. 多数元素189. 轮转数组121. 买卖股票的最佳时机122. 买卖股票的最佳时机 II55. 跳跃游戏274. H 指数380.…

word里的页码问题

一份文档写完&#xff0c;如果需要页码&#xff0c;第一页是封面&#xff0c;封面不需要页码怎么办&#xff1f; 解决&#xff1a;打开页眉页脚&#xff0c;然后把首页不同勾选上&#xff0c;这一页就没有页码了。 目录页&#xff0c;往往要使用罗马数字&#xff0c;其他正文又…

网络传输层协议:UDP和TCP

背景知识 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序&#xff1b; 在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信(可以通过 netstat -…

【用Vscode实现简单的python爬虫】从安装到配置环境变量到简单爬虫以及python中pip和request,bs4安装

第一步&#xff1a;安装python包 可以默认&#xff0c;也可以选择自己想要安装的路径 第二步&#xff1a;配置python环境变量&#xff0c;找到我的电脑->属性->高级 然后将刚刚安装的路径配置到path路径下&#xff1a; 然后cmd 运行 输入python命令&#xff0c;如果出现…

FFmpeg aresample_swr_opts的解析

ffmpeg option的解析 aresample_swr_opts是AVFilterGraph中的option。 static const AVOption filtergraph_options[] {{ "thread_type", "Allowed thread types", OFFSET(thread_type), AV_OPT_TYPE_FLAGS,{ .i64 AVFILTER_THREAD_SLICE }, 0, INT_MA…