泛型类有什么作用_3 分钟带你彻底搞懂 Java 泛型背后的秘密

优质文章,及时送达

274a2602ddc511dc1c168002657f9e9e.png

作者 | 的一幕

来源 | www.jianshu.com/p/dd34211f2565

这一节主要讲的内容是java中泛型的应用,通过该篇让大家更好地理解泛型,以及面试中经常说的泛型类型擦除是什么概念,今天就带着这几个问题一起看下:

举一个简单的例子:

9c1f78a48f70167a131b9ee22ba9d6aa.png

这里可以看出来在代码编写阶段就已经报错了,不能往string类型的集合中添加int类型的数据。

那可不可以往List集合中添加多个类型的数据呢,答案是可以的,其实我们可以把list集合当成普通的类也是没问题的,那么就有下面的代码:

b351b1b5daad4336e74e7553c92f6bd9.png

从这里可以看出来,不定义泛型也是可以往集合中添加数据的,所以说 泛型只是一种类型的规范,在代码编写阶段起一种限制。

下面我们通过例子来介绍泛型背后数据是什么类型

public class BaseBean {
T value;
public T getValue {
return value;
}
public void setValue(T value) {
this.value = value;
}
}

上面定义了一个泛型的类,然后我们通过反射获取属性和getValue方法返回的数据类型:

ac67e4882b48fc9a1bb480271e674ede.png58f97686fd115cca7369978e2b1b32a8.png

从日志上看到通过反射获取到的属性是Object类型的,在方法中返回的是string类型,因此咋们可以思考在getValue方法里面实际是做了个强转的动作,将object类型的value强转成string类型。是的,没错,因为泛型只是为了约束我们规范代码,而对于编译完之后的class交给虚拟机后,对于虚拟机它是没有泛型的说法的,所有的泛型在它看来都是object类型,因此泛型擦除是对于虚拟机而言的。

下面我们再来看一种泛型结构:

1eaca8192da9eaf0cda1ac85eb783efd.png

这里我将泛型加了个关键字extends,对于泛型写得多的伙伴们来说,extends是约束了泛型是向下继承的,最后我们通过反射获取value的类型是String类型的,因此这里也不难看出,加extends关键字其实最终目的是约束泛型是属于哪一类的。所以我们在编写代码的时候如果没有向下兼容类型,会警告错误的:

c808643c1f4467f2deda950f626457e7.png

大家有没有想过为啥要用泛型呢,既然说了泛型其实对于jvm来说都是Object类型的,那咱们直接将类型定义成Object不就是的了,这种做法是可以,但是在拿到Object类型值之后,自己还得强转,因此泛型减少了代码的强转工作,而将这些工作交给了虚拟机。

比如下面我们没有定义泛型的例子:

5d5797d0bb7cd36390703543a2fe69e7.png

势必在getValue的时候代码有个强转的过程,因此在能用泛型的时候,尽量用泛型来写,而且我认为一个好的架构师,业务的抽取是离不开泛型的定义。

常见的泛型主要有作用在普通类上面,

作用在抽象类、接口、静态或非静态方法上。

类上面的泛型

比如实际项目中,我们经常会遇到服务端返回的接口中都有errMsgstatus

等公共返回信息,而变动的数据结构是data信息,因此我们可以抽取公共的

BaseBean

public class BaseBean {
public String errMsg;
public T data;
public int status;
}

抽象类或接口上的泛型

//抽象类泛型
public abstract class BaseAdapter {
List DATAS;
}
//接口泛型
public interface Factory {
T create;
}
//方法泛型
public static T getData {
return ;
}

多元泛型

public interface Base {
void setKey(K k);
V getValue;
}

泛型二级抽象类或接口

public interface BaseCommon extends Base {
}
//或抽象类
public abstract class BaseCommon implements Base {
}

抽象里面包含抽象

public interface Base {
// void setKey(K k);
//
// V getValue;
void addNode(Map map);
Map getNode(int index);
}
public abstract class BaseCommon implements Base {
//多重泛型
LinkedList> DATAS = new LinkedList<>;
@Override
public void addNode(Map map) {
DATAS.addLast(map);
}
@Override
public Map getNode(int index) {
return DATAS.get(index);
}
}

>通配符

>通配符区别是>在你不知道泛型类型的时候,可以用>通配符来定义,下面通过一个例子来看看>的用处:

//定义了一个普通类
public class BaseBean {
T value;
public T getValue {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
//用来定义泛型的
public class Common1 extends Common {
}
cbdd4ea71425d9427aff2baa01cdcfcd.png

在定义的时候将Common的泛型指向Common1的泛型,可以看到直接提示有问题,这里可以想,虽然Common1是继承自Common的,但是并不代表BaseBean之间是等量的,在开篇也讲过,如果泛型传入的是什么类型,那么在BaseBean中的getValue返回的类型就是什么,因此可以想两个不同的泛型类肯定是不等价的,但是如果我这里写呢:

public static void main(String[] args) {
BaseBean commonBaseBean = new BaseBean<>;
//通配符定义就没有问题
BaseBean> common1BaseBean = commonBaseBean;
try {
//通过反射猜测setValue的参数是Object类型的
Method setValue = common1BaseBean.getClass.getDeclaredMethod("setValue

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

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

相关文章

实现Linux系统的回收站

今天偶然看到一个有意思的shell脚本&#xff0c;用脚本实现Linux系统下的回收站&#xff0c;推荐给大家。今天我们利用简单的shell脚本实现Linux系统下的回收站机制。先提供脚本代码[rootqll251 ~]# vim /bin/delete1 #! /bin/bash2 [ ! -d /.recycle ] && mkdir -v /.…

RobotFramework自动化测试框架的基础关键字(五)

1.1.1 Run Keyword If判断的使用 Run Keyword If是一个常用的用来做逻辑判断的关键字&#xff0c;意思是如果满足了某一个判断条件&#xff0c;然后就会执行关键字&#xff0c;我们对list3中放入0,1,2三个元素&#xff0c;然后遍历list3&#xff0c;判断当取到元素为0时…

python按位翻转_Python成为专业人士笔记-位操作符

“专业人士笔记”系列目录&#xff1a;创帆云&#xff1a;Python成为专业人士笔记--强烈建议收藏&#xff01;每日持续更新&#xff01;​zhuanlan.zhihu.com按位操作符直接操作二进制的字符串&#xff0c;这些是最基本的操作&#xff0c;并直接由中央处理器所支持。在处理设备…

我看三国有感而发

三国到现在已经过去一千多年了&#xff0c;关羽先生应该还淹没在失去荆州的痛苦中&#xff0c;关羽先生出现的时候充满了一股傲气&#xff0c;这种站着向上仰望30度角的男人非常稀有&#xff0c;应该是几百年才出现一个&#xff0c;而且还要生于乱世&#xff0c;可惜啊可惜&…

pil库修改图片大小_Gvcode库:一个更简单的、华人开源的、自动生成验证码的python库...

1 说明&#xff1a;1.1 gvcode全称&#xff1a;graphic-verification-code。1.2 基本介绍&#xff0c;一秒搞懂。1.3 并对源码进行修改一个小bug&#xff0c;教您如何修改源码&#xff0c;解决bug。2 准备&#xff1a;2.1 官网&#xff1a;https://pypi.org/project/graphic-ve…

iOS获取某个日期后n个月的日期

一、给一个时间&#xff0c;给一个数&#xff0c;正数是以后n个月&#xff0c;负数是前n个月&#xff1b;1 -(NSDate *)getPriousorLaterDateFromDate:(NSDate *)date withMonth:(NSInteger)month2 3 {4 5 NSDateComponents *comps [[NSDateComponents alloc] init];6 …

Android-AB系统OTA升级介绍

什么是OTA升级&#xff1f;OTA是Over-the-Air的简称&#xff0c;OTA升级可以理解为用户正常使用过程中进行升级&#xff0c;OTA 升级旨在升级基础操作系统、系统分区上安装的只读应用和/或时区规则。什么是Android AB系统更新A/B 系统升级&#xff0c;也叫做无缝更新&#xff0…

python输出进度条 tqdm_python-tqdm进度条

Tqdm 进度条可视化模块2018-12-04 14:34:25 使用python Tqdm进度条库让你的python进度可视化 Tqdm在阿拉伯语表示进步,在西班牙语中表示我非常爱你.是一个快速,可扩展的Python进度条, ...Python字符进度条Python字符进度条 看看这个神奇的module from tqdm import trange from …

看完少年的你,想到少年的我

别人喜欢听故事&#xff0c;所以我就讲故事&#xff0c;我可以不是现在的我&#xff0c;但是我还是原来的我&#xff0c;我从一个很小的地方来&#xff0c;我小时候&#xff0c;家里赚钱很难&#xff0c;读书是一件很苦的事情&#xff0c;但是呢&#xff0c;读书又是一件非常光…

伤感网络验证系统_知网查重报告单能造假?验证报告单真伪时,知网只给了这一个办法...

这是论文屋推送的第5篇文章&#xff0c;论文代发寻渠道&#xff0c;就到论文屋。现在的修图功能太强大了有木有&#xff1f;除了专业的一点的AdobePhotoshop之外&#xff0c;任何的一款修图软件甚至手机软件都可以更改一张图的任何地方&#xff0c;最重要的是&#xff0c;技术高…

jQuery: 整理3---操作元素的内容

1.html("内容") ->设置元素的内容&#xff0c;包含html标签&#xff08;非表单元素&#xff09; <div id"html1"></div><div id"html2"></div>$("#html1").html("<h2>上海</h2>") …

安卓系统监听system property值?

预备知识-什么是system propertysystem property是系统属性&#xff0c;以key-value格式保存。可以通过以下方式读取和修改system property的值&#xff1a;1.adbadb shell getprop <key> adb shell setprop <key> <value>2.C/Cint property_get(const char…

为什么全天坐在电脑前会让你精疲力竭

Tips 原文作者&#xff1a;Katie Heaney 原文地址&#xff1a;Why Sitting at Your Computer All Day Can Wipe You Out 像大多数日子一样&#xff0c;我昨天大部分时间坐在我认为是公寓最美丽的一角&#xff0c;一直在笔记本电脑打字。 我提交了一个故事&#xff0c;转述了几个…

这届全明星,把NBA又燃回来了

第一个罚球&#xff0c;戴维斯出手后&#xff0c;听到哐当医生&#xff0c;皮球掉了出来。我又紧张了。微信群了很多人开始发消息&#xff0c;说詹姆斯队又要输了。回到比赛。戴维斯当时没有任何微笑&#xff0c;我估计他内心也是紧张的&#xff0c;他有点埋怨哈登&#xff0c;…

PYTHON__ ITERTOOLS模块

组成 总体&#xff0c;整体了解 无限迭代器 迭代器 参数 结果 例子 count() start, [step] start, startstep, start2*step, ... count(10) --> 10 11 12 13 14 ... cycle() p …

redis分布式锁java代码_基于redis实现分布式锁

“ 在上一篇文章中介绍了动态配置定时任务&#xff0c;其中的原理跟spring 定时任务注解Scheduled一样的&#xff0c;都是通过线程池和定义执行时间来控制。来思考一个问题&#xff0c;如果我们的定时任务在分布式微服务里面呢&#xff1f;在分布式微服务里面一个微服务肯定可以…

数值字符串

加粗样式 数值与字符串 受限于电脑内存 数字 int float 布尔 none 列表list:l[1,2,3] l[1]2 字典表dict:d{‘name’;‘tom’,‘age’:20} d.get(‘name’) d[‘name’] 元组t(1,2,3,4) 元组与列表区别&#xff1a;列表可以改变相应下标数据&#xff0c;元组不行。 数值&#x…

C语言写个贪吃蛇游戏

贪吃蛇是个非常经典的游戏&#xff0c;用C语言来实现也是一个好玩的事情。这个游戏我写完后放在知乎&#xff0c;竟然点赞的人数超级多。我觉得大家喜欢&#xff0c;一个方面是因为写得简单&#xff0c;大家都能看得懂&#xff0c;一个可扩展性还是非常强的。我试了说一下这个代…

seir模型matlab_疫情专题 | 传染病的经典数学模型

在此次新冠肺炎疫情防控过程中&#xff0c;对疫情发展趋势的科学预测显得尤为重要。而这背后&#xff0c;离不开对传染病传播规律的建模。今天&#xff0c;小编就带各位数学学子们来了解一下传染病的四大经典数学模型&#xff1a;SI/SIS/SIR/SEIR。其中用到了许多微分方程的知识…

vlh 标签详解

1.vlh:root root标签做为所有vlh标签的根标签. 1)value 在给定的范围内&#xff0c;包含在ValueList或list的变量名. List的实例自动被DefaultListBackedValueList包装在ValueList中 2)id 如果有多个表被包含在一个request中&#xff0c;ID属性能区分每个表。id被追加到所…