java泛型中的extends和super

来源:互联网 发布:php sqlsrv扩展 编辑:程序博客网 时间:2024/05/16 23:58

泛型

泛型也是一种多态,只不过是编译时的多态。首先举一个简单的例子说明一下java泛型的语法:

class Base<T>{     private T t;     public void set(T t){this.t=t;System.out.println(t.getClass().getName());     }}public class Test {  public static void main(String[] args){      Base<Integer> b1=new Base<Integer>();      b1.set(new Integer(0));      Base<Double> b2=new Base<Double>();      b2.set(new Double(0)); }}

运行结果:

java.lang.Integerjava.lang.Double

java泛型区别C++泛型的一个明显特点就是不用template声明了,需要的时候直接在类名、接口名后或函数名前加<T>即可。

还有一点不一样,类型参数所支持的默认操作:

  • java泛型类型参数所定义的变量不支持基本的运算操作:

  • C++是可以的
template<class T>T add(const T& t1,const T& t2){      return t1+t2;}int _tmain(int argc, _TCHAR* argv[]){     cout<<add(4,5)<<endl;     system("pause");     return 0;}

 WildCards:通配符

在java泛型中,List<String>并不是List<Object>的子类(否则的话,List<String>容器中就可以加入非String类型的元素了),所以在一些抽象编程/面向接口编程(如函数参数传递以及返回值上)就会出现一些问题。

void printCollection(Collection<Object> c) {    for (Object e : c) {        System.out.println(e);    }}

虽然Object是所有类型的父类型,但Collection<Object>并不是所有容器的父容器,所以printCollection并不能接受诸如Collection<String>的参数。在这个问题上通配符就派上用场了。

void printCollection(Collection<?> c) {    for (Object e : c) {        System.out.println(e);    }}

 Collection<?>就可以用来表示所有容器的父容器了。

受限通配符:extends & super

extends的应用:

public abstract class Shape {    public abstract void draw(Canvas c);}public class Circle extends Shape {    private int x, y, radius;    public void draw(Canvas c) {        ...    }}public class Rectangle extends Shape {    private int x, y, width, height;    public void draw(Canvas c) {        ...    }}public class Canvas {    public void draw(Shape s) {        s.draw(this);   }public void drawAll(List<? extends Shape> shapes) {for(Shape s: shapes){             s.draw(this);}   }}

super的应用:

interface Sink<T> {    flush(T t);}public static <T> T writeAll(Collection<T> coll, Sink<? super T> snk) {    T last;    for (T t : coll) {        last = t;        snk.flush(last);    }    return last;}...Sink<Object> s;Collection<String> cs;String str = writeAll(cs, s);

如果是(Collection<? extends T>, Sink<T>),则的T的类型为Object,writeAll的返回类型为Ojbect而不是String。

还有两个经典应用:

<T extends Comparable<?super T>>
TreeSet(Comparator<? super E> c)

总结:

extends是上界限定符,如果传递的类型参数为某一类的子类或某个接口的实现,extends更适用,一般应用于类型多态时的参数传递或容器中的元素读取。

super是下界限定符,如果传递的类型参数为该类或该类的父类或该类实现的接口,super更适用,比如存在多种类型参数,需要将其限定为最具体的类型时。