E和? extends E 以及<? extends E> 和<? super E>
2014-03-30 15:30
260 查看
这是java的泛型语法,E表示泛型具现时使用的类,而? extends E则表示E的子类或者E的实现。
一开始接触的问题是,为什么需要? extends E这样的语法?
例如一个List<Number> numbList的add方法自然可以接受Number的子类,包括Double或者Integer。所以在add的参数只需要是add(E)就可以了,不需要add(? extends E)。
这是因为addAll方法的需要,addAll(Collection<? exntends E>)在这个接口里,如果使用addAll(Collection<E>)是不接受List<Double>作为参数的,这是因为按照官方的说法,java的泛型是“invariant”的。一个List<Double>不是一个List<Number>,确实一个List<? extends Number>。
值得注意的是,数组不一样,一个Double[]是一个Number[]。
参考:http://stackoverflow.com/questions/2770264/what-is-the-difference-between-e-extends-number-and-number
//Apple Orange 都继承自Fruit类,同时Jonathan是Apple的子类
List<? extends Fruit> list = new ArrayList<Apple>();
//list.add(new Apple());Error
//list.add(new Fruit());Error
List<? super Fruit> list = new ArrayList<Apple>();
list.add(new Apple());//可以
list.add(new Fruit());//可以
List<? extends Fruit> list = new ArrayList<Apple>();
list中为什么不能加入Fruit类和Fruit类的子类呢,原因是这样的
List<? extends Fruit>表示上限是Fruit,下面这样的赋值都是合法的
List<? extends Fruit> list1 = new ArrayList<Fruit>();
List<? extends Fruit> list2 = new ArrayList<Apple>();
List<? extends Fruit> list3 = new ArrayList<Jonathan>();
如果List<? extends Fruit>支持add方法的方法合法的话
list1可以add Fruit和所有Fruit的子类
list2可以add Apple和所有Apple的子类
list3可以add Jonathan和所有Jonathan的子类
这样的话,问题就出现了
List<? extends Fruit>所应该持有的对象是Fruit的子类,而且具体是哪一个
子类还是个未知数,所以加入任何Fruit的子类都会有问题,因为如果add Apple
的话,可能List<? extends Fruit>持有的对象是new ArrayList<Jonathan>()
Apple的加入肯定是不行的,如果 如果add Jonathan
的话,可能List<? extends Fruit>持有的对象是new ArrayList<Jonathan的子类>()
Jonathan的加入又不合法,所以List<? extends Fruit> list 不能进行add
而List<? super Fruit> list 表示list持有的对象是Fruit的父类,下限是 Fruit,所以list中add Fruit或Fruit的子类是没有问题的
一开始接触的问题是,为什么需要? extends E这样的语法?
例如一个List<Number> numbList的add方法自然可以接受Number的子类,包括Double或者Integer。所以在add的参数只需要是add(E)就可以了,不需要add(? extends E)。
这是因为addAll方法的需要,addAll(Collection<? exntends E>)在这个接口里,如果使用addAll(Collection<E>)是不接受List<Double>作为参数的,这是因为按照官方的说法,java的泛型是“invariant”的。一个List<Double>不是一个List<Number>,确实一个List<? extends Number>。
值得注意的是,数组不一样,一个Double[]是一个Number[]。
参考:http://stackoverflow.com/questions/2770264/what-is-the-difference-between-e-extends-number-and-number
//Apple Orange 都继承自Fruit类,同时Jonathan是Apple的子类
List<? extends Fruit> list = new ArrayList<Apple>();
//list.add(new Apple());Error
//list.add(new Fruit());Error
List<? super Fruit> list = new ArrayList<Apple>();
list.add(new Apple());//可以
list.add(new Fruit());//可以
List<? extends Fruit> list = new ArrayList<Apple>();
list中为什么不能加入Fruit类和Fruit类的子类呢,原因是这样的
List<? extends Fruit>表示上限是Fruit,下面这样的赋值都是合法的
List<? extends Fruit> list1 = new ArrayList<Fruit>();
List<? extends Fruit> list2 = new ArrayList<Apple>();
List<? extends Fruit> list3 = new ArrayList<Jonathan>();
如果List<? extends Fruit>支持add方法的方法合法的话
list1可以add Fruit和所有Fruit的子类
list2可以add Apple和所有Apple的子类
list3可以add Jonathan和所有Jonathan的子类
这样的话,问题就出现了
List<? extends Fruit>所应该持有的对象是Fruit的子类,而且具体是哪一个
子类还是个未知数,所以加入任何Fruit的子类都会有问题,因为如果add Apple
的话,可能List<? extends Fruit>持有的对象是new ArrayList<Jonathan>()
Apple的加入肯定是不行的,如果 如果add Jonathan
的话,可能List<? extends Fruit>持有的对象是new ArrayList<Jonathan的子类>()
Jonathan的加入又不合法,所以List<? extends Fruit> list 不能进行add
而List<? super Fruit> list 表示list持有的对象是Fruit的父类,下限是 Fruit,所以list中add Fruit或Fruit的子类是没有问题的
相关文章推荐
- <? extends T> 与 <? super T>的区别
- <? extends T>和<? super T> 差别
- AndroidManifest.xml中的<uses-feature>以及和<uses-permission>之间的联系
- < 基本功>short与Unsigned short以及Java基本类型
- 泛型中<? extends T>和<? super T> 差别
- <<异类 不一样的成功启示录>>笔记以及读后感
- <!DOCTYPE> 标签的含义以及是否可以省略
- 泛型之<T extends Comparable<? super T>>
- <? super T>与<? extends T>区别
- 从头认识Spring-1.16 SpEl对集合的操作(1)-建立集合以及访问集合的元素,以<util:list/>为例
- 一些html的缩写对应的意义以及常用单词的意思<新手向><持续更新>
- 简述泛型通配符<? extends T>和<? super T>
- <frameset>使用注意以及页面输入乱码解决
- 理解泛型通配符(List<? extends T > & List< ? super T>)
- difference between <? super T> and <? extends T> in Java
- 从头认识Spring-1.16 SpEl对集合的操作(1)-建立集合以及訪问集合的元素,以<util:list/>为例
- List<?super T> 和 Set<? extends T> 区别
- 简述泛型通配符<? extends T>和<? super T>
- (转)Java泛型<? extends T>和<? super T>