Java通配符上下界
首先,上下界是用于类型转换的,并不是主要用来往里面存放数据的。
容易陷入的一种误区是写好<? super X>以后,往里面添加X的父类,这是不行的。
上下界最常用的方式应该是这两个
List<? super Father> t3 = new ArrayList<GrandFather>();
List<? extends Father> t4 = new ArrayList<son>();
名称已经很说明关系了吧哈哈哈哈哈。
这时候,无论是t3还是t4,都没办法add(new GrandFather())
,没办法添加它们的父类。
首先,<? extends X>不支持像集合里面添加任何元素,因为extends所表示的Father或者它的儿子,但具体是哪个儿子,它是不知道的。但可以往外取元素,取的元素只能放在X或X的父类中,而不能是任何子类。
这里得明确一点,这个上下界通配指的是某一个子类或某一个父类,而不是所有子类或所有父类,基于这个,系统是不知道这个集合里存放的到底是哪一个类型的。只知道他们的上下边界在哪里。
嗯,<? super X>可以往里面添加X和X的子类。因为这里存放的一定是X的父类,那么是哪一个父类不知道,系统并不知道它的层级关系,所以存放父类是不可取的,但是可以存放子类,因为无论哪个子类都一定比X的层级要小。这里就体现了Java是可以自动向上转型,而不能自动向下转型的概念。基于此,取元素的时候只要用Object去存,就没有问题,因为Object是所有类的爸爸
package src.com.lzm;
import java.util.ArrayList;
import java.util.List;
class superGrandFather {
}
class GrandFather extends superGrandFather {
}
class Father extends GrandFather {
}
class Mother extends GrandFather {
}
class son extends Father {
}
public class superAndExtends {
public static void main(String[] args) {
List<? super Father> t = new ArrayList<>();
// t.add(new GrandFather());
// t.add(new superGrandFather());
t.add(new son());
t.add(new Father());
GrandFather object = (GrandFather) t.get(0);
List<? extends Father> t2 = new ArrayList<>();
Father father = t2.get(0);
List<? super Father> t3 = new ArrayList<GrandFather>();
List<? extends Father> t4 = new ArrayList<son>();
t3.add(new son());
}
}
注释掉的代码就是有问题的代码。