关于 extends T>, super T>的学习记录
2018-11-19 本文已影响0人
Hoker_
查看Rx源码时,看到了<? extends T>的使用,看的一头雾水,在网上查询一段时间后,这里对<? extends T>和<? super T>做一下理解笔记。
<? extends T>:是指 “上界通配符(Upper Bounds Wildcards)”
<? super T>:是指 “下界通配符(Lower Bounds Wildcards)”
无论是上届还是下界,其描述主体都是T:
- <? extends T>则表示T是最高的,也就是说,可以表示所有继承于T的(包括T)
- <? extends T>则表示T是最低的,也就是说,可以表示所有T的父类(包括T)
接下来对这些进行说明,先定义几个类:
public class Animal{}
public class Human extends Animal{}
public class Coder extends Human{}
public class Fish extends Animal{}
public class Shark extends Fish{}
public class Carp extends Fish{}
public class Boat<T>{
private T item;
public Boat(T t){item=t;}
public void set(T t){item=t;}
public T get(){return item;}
}
其继承结构如下:
继承结构
Boat则是一个容器类,用来放这些动物们。
首先,鲨鱼Shark显然也是鱼Fish,那么装鲨鱼的船(Boat<Shark>),和装鱼的船(Boat<Fish>),两者之间应该也能有一种关系:
两种船
简单点说,对于编译器而言:
- Shark IS A Fish
- SharkBoat IS NOT A FishBoat
Sun公司为了解决这个问题,就提出了<? extends T>和<? super T>
-
先说<? extends T>
<? extends Fish>表示任何装鱼的船,这样就能有:
<? extends Fish>
那么至于上界:
上界 -
再说<? super T>
<? super Fish>
那么至于下界:
下界
现在说下<? extends T>,<? super T>的副作用
-
上界<? extends T>不能往里存,只能往外取
就拿Boat<? extends Animal>来说,他可以表示图里的所有的船,那存的时候编译器该如何考虑能存啥呢?是Human、还是Fish,显然这是两个东西,虽然都继承于Animal,所以编译器干脆就都不让存了,只能读,而读是没有问题的,因为不管怎么读都是Animal。 -
下界<? super T>可以存,但往外取只能放在Object对象里
就拿Boat<? extends Shark>来说,如图所示,可以保持其全部子类。然而对于取,显然就搞不清楚该用Shark、Fish还是Animal来表示了,明显的"Shark IS A Fish" 但 "Fish IS NOT A Shark" ,所以只能用Object这个所有的父类来展示了。
下界set()