美文网首页
Java泛型之super和extents

Java泛型之super和extents

作者: 蜗蜗牛牛 | 来源:发表于2018-11-21 17:20 被阅读14次

一直对<? super XX> 和<? extends XX>很疑惑,下面用代码来记录一下他们的区别

首先,创建三个类:

class Employee {
}

class Manager extends Employee {
}

class Ceo extends Manager {
}

他们之间的集成关系很简单,然后分别看一下他们在extends和super中的表现:

public void testExtends(List<? extends Manager> list) {
    list.add(new Employee());//报错
    list.add(new Manager());//报错
    list.add(new Ceo());//报错
    //由上面三行可以看出,extends不可以加入
    /*
     *报错原因:
     * add(capture<? extends Manager>) int List cannot be applied to Employee/Manager/Ceo
     *
     *分析:
     * capture<? extends Manager> :捕获到Manager的子类
     *
     * 整句话的意思是:
     *      add()方法接收的是Manager的一个不确定的子类,所以不能添加...;
     *
     * 先看Employee,它是Manager的父类,直接就不满足子类这个条件,所以报错
     *
     * 再看Manager和Ceo,它们都是一个确定的子类,不一定是list的需要的元素,所以报错
     */

    Manager manager = list.get(0);
    //由上面可以看出,extends可以取出,而且取出的是Manager
    /*
     *为甚取出的是Manager?
     * list里面装的是Manager的某种不确定的子类,但是不管是哪一种,它肯定是一个Manager
     */
}

public void testSuper(List<? super Manager> list) {
    list.add(new Employee());//报错
    list.add(new Manager());//正常
    list.add(new Ceo());//正常
    //由上面三行可以看出,extends可以加入Manager及其子类,但不可以加入其父类

    /*
     *错误原因:
     *  add (capture<? super Manager>) in List cannot be applied to Employee
     *
     *分析:
     *  capture<? super Manager>: 捕获到Manager的父类;
     *  整句话的意思是:
     *      add()方法接收的是Manager的不确定的父类,不能直接应用于Employee
     *
     *  可以添加Manager及其子类就正常了,这个list的元素既然是Manager的父类,那么肯定是可以用来装他的子类的啦。
     */

    Object object = list.get(0);
    //由上面可以看出,extends取出的是一个Object,如果要使用具体的类型,需要强制转换
    /*
     *为甚取出来的是一个Object呢?
     * 还是因为存入元素只是指明了是Manager的父类,但是没有指明具体的类型,那么就只能给一个所有类的父类Object啦
     */
}

结论:
      作为容器的元素,
                <? extends XX>,容器不可以增加元素,但是可以获取元素;
                <? super XX>,容器可以增加元素,但是获取的元素是Object.

然后,再来看一下他们作为参数传递时的情况:

public void test() {
    List<Employee> employees = new ArrayList<>();
    List<Manager> managers = new ArrayList<>();
    List<Ceo> ceos = new ArrayList<>();

    testExtends(employees);//报错
    testExtends(managers);//正常
    testExtends(ceos);//正常
    //由上面三行可以看出,Extends可以接收Manager的子类
    /*
     *报错原因:
     * testExtends(java.util.List<? extends Manager>) cannot be applied to java.util.List<Employee>
     *
     * 整句话的意思是:
     *      testExtends()接收一个List,这个List的元素是Manager的子类,
     *      但是employees的元素Employee不是Manager的子类,所以不接收List<Employee>
     *
     * 同理,managers和ceos的元素都是Manager的子类,所以可以接收
     */

    testSuper(employees);//正常
    testSuper(managers);//正常
    testSuper(ceos);//报错
    //由上面三行可以看得出,super可以接收Manager的父类
    /*
     *报错原因:
     * testSuper(java.util.List<? super Manager>) cannot be applied to java.util.List<Ceo>
     *
     * 整句话的意思是:
     *      testSuper()接收一个List,这个List的元素是Manager的父类,
     *      但是ceos的元素Ceo不是Manager的父类,所以不接收ceos
     *
     * 同理,managers和employees的元素都是Manager的父类,所以可以接收
     */
}

结论:
    对于作为参数传递来说,
          <? extends XX> 参数接收XX的子类,不接收它自身以外的父类;
          <? super XX>参数接收XX的父类,不接受它自身以外的子类。

相关文章

网友评论

      本文标题:Java泛型之super和extents

      本文链接:https://www.haomeiwen.com/subject/yxicqqtx.html