`

Java泛型通配符extends与super

 
阅读更多

Java 泛型

关键字说明

  • ? 通配符类型
  • <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类
  • <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object

extends 示例

static class Food{}
static class Fruit extends Food{}
static class Apple extends Fruit{}
static class RedApple extends Apple{}

List<? extends Fruit> flist = new ArrayList<Apple>();
// complie error:
// flist.add(new Apple());
// flist.add(new Fruit());
// flist.add(new Object());
flist.add(null); // only work for null 

List<? extends Frut> 表示 “具有任何从Fruit继承类型的列表”,编译器无法确定List所持有的类型,所以无法安全的向其中添加对象。可以添加null,因为null 可以表示任何类型。所以List 的add 方法不能添加任何有意义的元素,但是可以接受现有的子类型List<Apple> 赋值。

Fruit fruit = flist.get(0);
Apple apple = (Apple)flist.get(0);

由于,其中放置是从Fruit中继承的类型,所以可以安全地取出Fruit类型。

flist.contains(new Fruit());
flist.contains(new Apple());

在使用Collection中的contains 方法时,接受Object 参数类型,可以不涉及任何通配符,编译器也允许这么调用。

super 示例

List<? super Fruit> flist = new ArrayList<Fruit>();
flist.add(new Fruit());
flist.add(new Apple());
flist.add(new RedApple());

// compile error:
List<? super Fruit> flist = new ArrayList<Apple>();

List<? super Fruit> 表示“具有任何Fruit超类型的列表”,列表的类型至少是一个 Fruit 类型,因此可以安全的向其中添加Fruit 及其子类型。由于List<? super Fruit>中的类型可能是任何Fruit 的超类型,无法赋值为Fruit的子类型Apple的List<Apple>.

// compile error:
Fruit item = flist.get(0);

因为,List<? super Fruit>中的类型可能是任何Fruit 的超类型,所以编译器无法确定get返回的对象类型是Fruit,还是Fruit的父类Food 或 Object.

小结

 

extends 可用于的返回类型限定,不能用于参数类型限定。
super 可用于参数类型限定,不能用于返回类型限定。
分享到:
评论

相关推荐

    Java泛型中? super T和? extends T的区别

    extends T&gt;表示包括T在内的任何T的子类,下面我们详细分析一下两种通配符具体的区别。  extends  List&lt;? extends Number&gt; foo3的通配符声明,意味着以下的赋值是合法的:  // Number "extends" Number (in...

    Java泛型深入学习和总结 看这一篇就足够!

    二 泛型类、泛型接口、泛型方法、泛型通配符 2.1 泛型类: 2.2 泛型接口: 2.3 泛型方法: 2.4 泛型通配符: 三 限定类型变量 四 泛型中的约束和局限性 4.1 不能用基本类型实例化类型参数 4.2 运行时类型查询只适用...

    泛型中? super T和? extends T的区别

    经常发现有List&lt;? super T&gt;、Set&lt;? extends T&gt;的声明,是什么意思呢?&lt;? super T&gt;表示包括T在内的任何T的父类,&lt;? extends T&gt;表示包括T在内的任何T的子类,下面我们详细分析一下两种通配符具体的区别。

    廖雪峰 Java 教程.doc

    extends通配符 super通配符 泛型和反射 集合 Java集合简介 使用List 编写equals方法 使用Map 编写equals和hashCode 使用EnumMap 使用TreeMap 使用Properties 使用Set 使用Queue 使用PriorityQueue ...

    Java中List<? extends T>与List<? super T>的区别(值得珍藏)

    表示类型通配符,即具体传什么参数类型,在List定义时不用考虑。 这里的 &lt;T&gt; 表示泛型,T 表示泛型中装载的类型为T类型,等到需要的时候,我们可以具体这个 T。我们在使用动态数组实现 ArrayList 的时候,如果希望...

    \java超强笔记(超级经典)

    &lt;?&gt; 泛型通配符表示任意类型,仅用于传参 &lt;? extends 类型&gt; 表示这个类型可以是该类或者该类的子类。 &lt;? super 类型&gt; 表示这个类型可以是该类或者该类的父类。 泛型的优点: 指定泛型后,取出...

    java8集合源码分析-Project:工程目录

    限定通配符和非限定通配符、上下界限定符extends 和 super List和原始类型List之间的区别? List&lt;?&gt;和List之间的区别是什么? 单元测试 junit、mock、mockito、内存数据库(h2) 正则表达式 java.lang.util....

    Kotlin中协变、逆变和不变示例详解

    super T&gt; 通配符型变约束,而是采用类似 C# 的 in,out 用于支持协变和逆变,这同时避免了处理子类型化,父类化的问题(即Java泛型中典型的List&lt;T&gt; 不是 List&lt;Object&gt;的子类型的问题); 基本的泛型语法可以...

    Java 高级特性.doc

    通配符引用之前调用,否则就与java 5提供泛型的目的背道而驰了。 b..向下限定通配符: 正确:Vector&lt;? extends Number&gt; x = new Vector(); 错误:Vector&lt;? extends Number&gt; x = new Vector(); 向上限定通配符: ...

    存取原则和PECS法则

    super” 通配符的特征,我们可以得出以下结论: 如果你想从一个数据类型里获取数据,使用 ? extends 通配符 如果你想把对象写入一个数据结构里,使用 ? super 通配符 如果你既想存,又想取,那就别用通配符。

Global site tag (gtag.js) - Google Analytics