文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

5分钟Java短文:泛型之逆变和协变

2024-12-10 16:12

关注

本文转载自微信公众号「咸鱼正翻身」,作者MDove  。转载本文请联系咸鱼正翻身公众号。 

前言

日常琐碎的时间下,不适合看一些长篇高质量的文章,但是琐碎时间也是时间,看一些短小精悍的文章来查缺补漏也是极好的。碎花化的时间,就交给“碎片化的文章”来填充吧。

今天“碎片化文章”主题:泛型-逆变和协变。逆变和协变摆在这我猜很多朋友会蒙蔽,毕竟我们日常好像、大概没怎么接触过这个概念。

事实并非如此,我们日常开发中经常见,只是不知道这么个名词而已。

正文

OK,今天5分钟短文就让咱们聊一聊逆变和协变这俩个概念。

1、基础概念

其实它们俩的概念很好理解。接下来让我们仔细读一遍下边的这一段话:

逆变与协变用来描述类型转换后的继承关系。如果A、B表示类型,f(...)表示类型转换,≤表示继承关系(比如,A≤B表示A是B的子类)

如果f(...)是逆变的,那么当A≤B时则f(B)≤f(A)成立

如果f(...)是协变的,那么当A≤B时则f(A)≤f(B)成立

额外补充一条:如果f(...)是不变的,那么当A≤B时则f(B)与f(A)没有任何关系

2、代码场景

如果大家充分理解了上边的话,其实就能想到咱们日常代码中的例子:数组就是一种协变;泛型是不变的。上代码:

  1. public class A extends B {} 
  2.  
  3. public class B {} 
  4.  
  5.  
  6.  
  7.  
  8. public void test() { 
  9.  
  10. B[] arrs = new A[66]; 
  11.  
  12. List list = new ArrayList(); 
  13.  

这段代码是编不过的:

 

因为数组是协变的,所以 A[]是 B[]的子类;而泛型不是,所以 List并不是 List的子类。

3、通配符的意义

因为这个原因的存在,所以才有了通配符。

3.1、协变-上限通配符

代码改成这个样子就可以正常编译了:

 

通配符的存在,让泛型产生了协变,让 List可以变成 List的子类。不过我猜经验丰富的同学已经知道,这样搞“没什么卵用”,因为:

 

我们发现,这样搞完。对于 list变量来说,我们只能 get()不能 add()!一时接受不了?其实这里也很好理解,协变之后对于list来说,我可以指向很多 List的子类。

假设此时我们可以随意 add(),那么对于运行期来说简直是灾难:因为我可以随意的 add(newA());add(newC())。如果这种情况存在那么我 get()的时候,是不是只能把它当做 B来使用,因为这里有可能有 A也有可能有 C...

这样搞完全没有意义...因此也就有了下边的内容:逆变-下限通配符

3.2、逆变-下限通配符

直接上代码:

  1. public class A extends B {} 
  2.  
  3. public class B {} 
  4.  
  5. public class C extends B {} 
  6.  
  7. public class D extends A {} 
  8.  
  9.  
  10.  
  11.  
  12. public void test2(List list){ 
  13.  
  14. list.add(new A()); 
  15.  
  16. list.add(new B()); 
  17.  
  18. list.add(new C()); 
  19.  
  20. list.add(new D()); 
  21.  

此时我们会发现:我们可以 add(), A及其子类。而这种实现就脱胎于咱们逆变这个概念。

 

3.3、小思考

如果我们仔细想一想会发现,这些都是在开发阶段或者编译阶段的限制。做了这么多限制,到底为了什么?或者收益是什么样的呢?

关于这部分内容的讨论,咱们后续再聊~

尾声

到此想聊的内容就结束了,关于泛型的话题还有很多很多,而熟练的使用和理解泛型对咱们编写工具、框架有着关键的帮助。

 

来源:咸鱼正翻身内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯