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. [USACO09OPEN]Ski Lessons

    嘟嘟嘟 先考虑这两点: 1.如果我们有结束时间相同的课程,且达到的能力相同,那么我们一定选择开始时间最晚的. 2.如果有能力值相同的滑雪坡,我们一定选择时间最短的. 因此先预处理两个数组.cla[i] ...

  2. --provider=docker时出现的问题

    Vagrantfile类似: Vagrant.configure(") do |config| config.vm.box = "hashicorp/precise64" ...

  3. virtualbox+vagrant学习-2(command cli)-10-vagrant Port命令

    Port 格式: vagrant port [options] [name|id] 端口命令显示映射到主机端口的客户端口的完整列表 userdeMacBook-Pro:~ user$ vagrant ...

  4. flex布局中flex-shrink的计算规则

    下面代码来自MDN html部分: <p>the width of content is 500px, flex-basic of flex item is 120px.</p> ...

  5. two sum[easy]

    Given an array of integers, return indices of the two numbers such that they add up to a specific ta ...

  6. C中typedef 函数指针的使用

    类型定义的语法可以归结为一句话:只要在变量定义前面加上typedef,就成了类型定义.这儿的原本应该是变量的东西,就成为了类型. int integer;     //整型变量int *pointer ...

  7. Kafka设计解析(九)为何去掉replica.lag.max.messages参数

    转载自 huxihx,原文链接 Kafka副本管理—— 为何去掉replica.lag.max.messages参数 在Kafka设计解析(二)Kafka High Availability (上)文 ...

  8. Android攻城狮学习笔记-进阶篇一

    点击快速抵达: 第1章 AndroidManifest配置文件 第2章 使用ListView显示信息列表 第3章 使用DatePicker及TimePicker显示当前日期和时间 第4章 使用Grid ...

  9. CentOS6中OpenMP的运行时间或运行性能分析

    OpenMp作为单机多核心共享内存并行编程的开发工具,具有编码简洁等,容易上手等特点. 关于OpenMP的入门,博主饮水思源(见参考资料)有了深入浅出,循序渐进的分析.做并行开发,做性能分析是永远逃避 ...

  10. UCOSii和Linux的区别和联系

    UCOSii和Linux的区别和联系 想通过UCOSii来理解Linux的系统架构,故参考一些资料,简单整理了一下UCOSii和Linux的区别和联系,以此来更好的学习Linux. 其具体对比如下: ...