专注于快乐的事情

Java泛型介绍

本文于1135天之前发表,文中内容可能已经过时。

super和extents

List<? extends E>表示该list集合中存放的都是E的子类型(包括E自身),由于E的子类型可能有很多,但是我们存放元素时实际上只能存放其中的一种子类型(这是为了泛型安全,因为其会在编译期间生成桥接方法该方法中会出现强制转换,若出现多种子类型,则会强制转换失败),例子如下:

List<? extends Number> list=new ArrayList<Number>();
        list.add(4.0);//编译错误
        list.add(3);//编译错误

上例中添加的元素类型不止一种,这样编译器强制转换会失败,为了安全,Java只能将其设计成不能添加元素。

虽然List<? extends E>不能添加元素,但是由于其中的元素都有一个共性–有共同的父类,因此我们在获取元素时可以将他们统一强制转换为E类型,我们称之为get原则。

对于List<? super E>其list中存放的都是E的父类型元素(包括E),我们在向其添加元素时,只能向其添加E的子类型元素(包括E类型),这样在编译期间将其强制转换为E类型时是类型安全的,因此可以添加元素,例子如下:
List<? super Number> list=new ArrayList();
list.add(2.0);
list.add(3.0);
但是,由于该集合中的元素都是E的父类型(包括E),其中的元素类型众多,在获取元素时我们无法判断是哪一种类型,故设计成不能获取元素,我们称之为put原则。

实际上,我们采用extends,super来扩展泛型的目的是为了弥补例如List只能存放一种特定类型数据的不足,将其扩展为List<? extends E> 使其可以接收E的子类型中的任何一种类型元素,这样使它的使用范围更广。

Java 和 Scala 均支持协变,逆变和非转化类型。然而,在 Scala 中,转化行为的定义是类型声明的一部分,称为转化标记(variance annotation)。

而Java 中参数化的类型在定义时并未声明继承转化行为,而是在使用该类型时,也就是在声明变量时,才指定参数化类型的转化行为。

WoodDuck 》 Duck 》Animal

定义一个zoo对象,可以新增动物。

public class Zoo<T> {
    List<Object> list = new ArrayList();

    public void add(T animal) {
        list.add(animal);
    }
}


public class ZoosTest {
    public static void main(String[] args) {
        Zoo<Animal> zoo = new Zoo<Animal>();
        zoo.add(new Duck());

       // Zoo<Animal> zoo1 = new Zoo<Duck>(); //编译错误
    }
}

Zoo zoo1 = new Zoo()出现编译错误?

如何解决? <? extends T>和<? super T>就是为此出现的。

super表示下界,而extends表示上界

super的使用举例,

 public static void main(String[] args) {
    List<? super Duck> list3 = new ArrayList<Duck>();
    list3.add(new Duck());
    list3.add(new WoodDuck());
   // list3.add(new Animal());
    List<? super Duck> list4 = new ArrayList<Animal>();
    list4.add(new Duck());
    list4.add(new WoodDuck());
    //list4.add(new Animal());

    //List<? super Duck> list5 = new ArrayList<WoodDuck>(); //不是父类,不能编译
}

List<? super Duck> list3 表示元素父类至少为Duck

extends举例

List<? extends Duck> list3 = new ArrayList<Duck>();
       list3.add(new WoodDuck());

会出现编译错误

下面的是正确的

List< Duck> list3 = new ArrayList<Duck>();
    list3.add(new WoodDuck());

参考网站

评论系统未开启,无法评论!