Java的类型通配符,可以出现在类、方法上面。最常用的方式就是集合类,例如List,Set等类上面。

通配符类型

  • 有泛型参数 List
  • 有无类型标识 List< ? >
  • 有通用的标识 List< object >
  • 边界通配符 List<? extends Class>
  • 边界通配符 List<? super Class>

本文主要讨论的是最后的关于边界的通配符类型。

看一个例子

public static void main(String[] args) {
List<B> bList = new ArrayList();
bList.add(new A());
bList.add(new B());
bList.add(new C());
A a3 = bList.get(0);
B b3 = bList.get(0);
C C3 = bList.get(0); List<? extends B> bExtends = new ArrayList();
bExtends.add(new A());
bExtends.add(new B());
bExtends.add(new C());
A a1 = bExtends.get(0);
B b1 = bExtends.get(0);
C C1 = bExtends.get(0); List<? super B> bSuper = new ArrayList();
bSuper.add(new A());
bSuper.add(new B());
bSuper.add(new C());
A a2 = bSuper.get(0);
B b2 = bSuper.get(0);
C C2 = bSuper.get(0);
}
}
class A {
String a = "a";
}
class B extends A {
String b = "b";
}
class C extends B {
String c = "c";
}

有三个类,继承关系是A < B < C。

然后声明了三个数组,list,extends,super.

上面的代码是编译不通过的。分别在第3、7、11-13、16、19、22-24行。

原理分析

List<? extends B> 得到的是B及B的子类的一个集合。

List<? super B> 得到的是B及B的父类的一个集合。

List 得到的是一个B的集合。

  1. ? extends B 声明了上界标识符、不定下界,而add(E e)的时候,编译器无法确定e需要分配的声明类型,虽然有实际类型,这个地方跟多态不一致,所以编译器不通过;而get(int i)的操作,会获取到一个肯定是B的元素,故是安全的。
  2. ? super B正相反,声明的是下界标识符、不定上界(Object),当add(E e)的时候,添加的是子类型,子类型向上转型是安全的;get(int i)的时候,并不能确定拿到的会是一个怎样的类型,可能是Object,也能是A,故也是违规的。
  3. B 声明的是上下界为B。add(E e)按照多态性,可以添加为B的类型及其子类型;get(int i)返回的必然是B的类型。

代码错误验证

按照第1条解释,第3、11-13行的错误符合解释。

按照第2条解释,第19、22-24行的错误符合解释。

第7、16行是由于向下转型是不安全的,股编译错误。

小结

extends和super别定义了上下限,结论如下面的表格

extends super T
add unsafe safe safe
get safe unsafe safe

Java那些事-泛型通配符的更多相关文章

  1. 【Java】java 中的泛型通配符——从“偷偷地”地改变集合元素说起

    一直没注意这方面的内容,想来这也算是基础了,就写了这个笔记. 首先java的通配符共有三种----先别紧张,现在只是粗略的过一下,看不看其实无所谓 类型 介绍 <?> 无限定通配符,等价于 ...

  2. JAVA基础补漏--泛型通配符

    泛型通配符只能用于方法的参数 不能用对象定义 public class Test { public static void main(String[] args) { ArrayList<Str ...

  3. 简谈 Java 中的泛型通配符

    很好的一篇文章https://zhuanlan.zhihu.com/p/26681625

  4. java泛型通配符?

    转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T  有类型 ?  未知类型 一.通配符的上界 既然知道List<Cat>并不是Lis ...

  5. 黑马程序员——JAVA基础之泛型和通配符

    ------- android培训.java培训.期待与您交流! ---------- 泛型:            JDK1.5版本以后出现新特性.用于解决安全问题,是一个类型安全机制. 泛型好处: ...

  6. Java 泛型 通配符类型

    Java 泛型 通配符类型 @author ixenos 摘要:限定通配符类型.无限定通配符类型.与普通泛型区别.通配符捕获 通配符类型 通配符的子类型限定(?都是儿孙) <? extends ...

  7. java里程碑之泛型--类型通配符

    1,泛型与数组在子类上面的对比 在整理java泛型的类型通配符之前,我们先来研究下java在数组设计上的一个不合理.我们来看下面代码: public class Test { public stati ...

  8. -1-3 java集合框架基础 java集合体系结构 Collection 常用java集合框架 如何选择集合 迭代器 泛型 通配符概念 Properties 集合 迭代器

    集合又称之为容器存储对象的一种方式 •数组虽然也可以存储对象,但长度是固定的:显然需要可变长度的容器 集合和数组的区别?                 A:长度区别                  ...

  9. [转]JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别

    原文地址:https://www.jianshu.com/p/95f349258afb 1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被 ...

  10. java泛型---通配符,泛型嵌套

    package generic; import java.util.ArrayList; import java.util.List; /** * ? -->通配符,类型不确定,用于声明 变量| ...

随机推荐

  1. 2002. [HNOI2010]弹飞绵羊【LCT】

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  2. 【洛谷】【动态规划+单调队列】P1725 琪露诺

    [题目描述:] 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精. 某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到河 ...

  3. Discuz!教程之删除注释云平台JS,加快DISCUZ访问

    很多站长反应打开网站的时候有个http://discuz.gtimg.cn/cloud/scripts/discuz_tips.js?v=1一直在加载中,导致网页打开速度很慢,这个时候你可以按本文教程 ...

  4. [luogu2668] 斗地主

    题面 ​ 这好像就是道**暴搜题, 由于可以回溯, 所以顺序其实没有多大的关系, 见代码吧... 具体代码 #include <iostream> #include <cstring ...

  5. 初识Qt文件下载

    1.新建一个Qt Gui应用,项目名称为http,基类选择为QMainWindow,类名设置为MainWindow. 2.在http.pro文件中的QT  += core gui后添加\ networ ...

  6. Spring源码分析(十二)FactoryBean的使用

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 一般情况下,Spring通过反射机制利用bean的class属性指定实现 ...

  7. HDU 1251 统计难题(字典树入门模板题 很重要)

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submi ...

  8. KVM虚拟机IO处理过程(二) ----QEMU/KVM I/O 处理过程

    接着KVM虚拟机IO处理过程中Guest Vm IO处理过程(http://blog.csdn.net/dashulu/article/details/16820281),本篇文章主要描述IO从gue ...

  9. docker~dockertoolbox的加速器

    对于在win10以下的操作系统上跑docker,我们可以安装docker toolbox工具,下载安装后第一次启动它会从远程github上下载最新版的boot2docker镜像文件,40多兆,但下载非 ...

  10. BCNF范式及其分解方法(对一次Lab作业的总结)

    BCNF是比第三范式更严格一个范式.它要求关系模型中所有的属性(包括主属性和非主属性)都不传递依赖于任何候选关键字.也就是说,当关系型表中功能上互相依赖的那些列的每一列都是一个候选关键字时候,该满足B ...