文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java generic中通配符的理解有哪些

2023-06-17 10:52

关注

本篇文章给大家分享的是有关Java generic中通配符的理解有哪些,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

置换原则

结合Java本身的一些面向对象的特性,我们很容易理解这么一个置换原则:

一个指定类型的变量可以被赋值为该类型的任何子类;一个指定某种类型参数的方法可以通过传入该类型的子类来进行调用。

总的来说,就是说我们使用的任何类型变量都可以用该类型的子类型来替换。

泛型中一种错误的继承关系

在泛型的编程中,我们考虑到子类型关系的时候,容易把一种关系给弄混淆,并错误的采用置换原则。

比如说:

List<Integer> ints = new ArrayList<Integer>();  ints.add(1);  ints.add(2);  List<Number> nums = ints; // compile error

在这段代码中,我们看到类型参数Integer是Number的子类型,就容易想当然的认为List<Integer>也是List<Number>的子类。实际上并不是。所以才会导致类型不匹配,产生编译时错误。

有点时候,我们觉得,这样的转换看似不能用到一个好处,就是利用对象之间继承的关系。要是我们能有一个列表,它既能处理某种类型的数据,还能处理该类型的所有子类型的数据,这样岂不是既能用到泛型的好处又可以用到对象关系的好处么?于是在这里就引出了通配符(wildcard)。

通配符(Wildcard)

在Java类库中Collection接口定义中有一个用到通配符的方法:

interface Collection<E> {  ...  public boolean addAll(Collection<? extends E> c);  ...  }

在addAll方法的描述里,可以接受Collection类型的参数。其中Collection中的类型参数可以为任何继承E的子类型。

因此,我们可以在实际代码中这么使用:

List<Number> nums = new ArrayList<Number>();  List<Integer> ints = Arrays.asList(1, 2);  List<Double> dbls = Arrays.asList(2.78, 3.14);  nums.addAll(ints);  nums.addAll(dbls);

在代码中我们可以看到,List<Integer>和List<Double>都是Collection<? extends Number>类型的子类。所以上面的方法中可以将Integer和Double两种类型的List传入到方法中。

通配符使用限制1:

使用通配符的泛型数据类型比较有意思,既然前面我们可以将其作为方法声明的参数,那么是否可以将它作为一个变量类型来直接创建变量呢?

看如下代码:

List<? extends Number> nums = new ArrayList<Integer>(); //compile error

实际上上面这段代码是编译通不过的。

通配符使用限制2:

既然不能用来直接创建变量对象,那么再看下面这段代码:

List<Integer> ints = new ArrayList<Integer>();  ints.add(1);  ints.add(2);  List<? extends Number> nums = ints;  nums.add(3.14); // compile error

这段代码的第5行会导致编译错误。在第4行代码中,我们将ints赋值给nums,表面上nums声明为一个List<Integer>的父类型,所以第4行编译正常。为什么第5行代码会出错呢?表面上看来,既然nums类型可以接受继承自Number的所有参数,那加一个Double类型的数据应该是没问题的。实际上我们再考虑一下这样会带来的问题:

nums本来引用的是一个继承自该类型的List<Integer>,如果我们允许加入Double类型的数据的话,那么ints这个Integer的List里面就包含了Double的数据,当我们使用ints的时候,和我们所期望的只包含Integer类型的数据不符合。

因此,这段代码也说明了一个问题,就是在? extends E这种通配符引用的数据类型中,如果向其中增加数据操作的话会有问题。所以向其中增加数据是不允许的。但是我们可以从其中来读取数据。

总结:

通配符修饰的泛型不能用来直接创建变量对象。

通配符修饰相当于声明了一种变量,它可以作为参数在方法中传递。这么做带来的好处就是我们可以将应用于包含某些数据类型的列表的方法也应用到包含其子类型的列表中。相当于可以在列表中用到一些面向对象的特性。

以上就是Java generic中通配符的理解有哪些,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

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

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

软考中级精品资料免费领

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

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

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

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

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

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

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