查看: 102|回复: 0

Java那些事—泛型通配符

发表于 2018-6-14 13:58:07
Java的类型通配符,可以出现在类、方法上面。最常用的方式就是集合类,例如List,Set等类上面。
通配符类型
有泛型参数 List
有无类型标识 List< ? >
有通用的标识 List< object >
边界通配符 List
边界通配符 List
本文主要讨论的是最后的关于边界的通配符类型。
看一个例子
public static void main(String[] args) { List 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 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 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 得到的是B及B的子类的一个集合。
List 得到的是B及B的父类的一个集合。
List 得到的是一个B的集合。
? extends B 声明了上界标识符、不定下界,而add(E e)的时候,编译器无法确定e需要分配的声明类型,虽然有实际类型,这个地方跟多态不一致,所以编译器不通过;而get(int i)的操作,会获取到一个肯定是B的元素,故是安全的。
? super B正相反,声明的是下界标识符、不定上界(Object),当add(E e)的时候,添加的是子类型,子类型向上转型是安全的;get(int i)的时候,并不能确定拿到的会是一个怎样的类型,可能是Object,也能是A,故也是违规的。
B 声明的是上下界为B。add(E e)按照多态性,可以添加为B的类型及其子类型;get(int i)返回的必然是B的类型。
代码错误验证
按照第1条解释,第3、11-13行的错误符合解释。
按照第2条解释,第19、22-24行的错误符合解释。
第7、16行是由于向下转型是不安全的,股编译错误。
小结
extends和super别定义了上下限,结论如下面的表格
extendssuperTaddunsafesafesafegetsafeunsafesafe
欢迎工作一到五年的java程序员朋友们加入Java架构开发:744677563
本群提供免费的学习指导 架构资料 以及免费的解答
不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导



回复

使用道具 举报