0
点赞
收藏
分享

微信扫一扫

java泛型中的通配符使用及PECS原则

一.通配符使用

一.?

通配符的主要作用就是让泛型能够接受未知类型的数据。

Ep:

publicclass GernericTest {
publicstaticvoid main(String[] args) throws Exception{
List<Integer> listInteger =new ArrayList<Integer>();
List<String> listString =new ArrayList<String>();
printCollection(listInteger);
printCollection(listString);
}
publicstaticvoid printCollection(Collection<Object> collection){
for(Object obj:collection){
System.out.println(obj);
}
}
}

java泛型中的通配符使用及PECS原则_子类

结果报错,因为Integer和Object不兼容。(注:这里是容器内存储的类型,不能进行类型向上转换)

publicclass GernericTest {
publicstaticvoid main(String[] args) throws Exception{
List<Integer> listInteger =new ArrayList<Integer>();
List<String> listString =new ArrayList<String>();
printCollection(listInteger);
printCollection(listString);
}
publicstaticvoid printCollection(Collection<?> collection){
for(Object obj:collection){
System.out.println(obj);
}
}
}

修改后?代表着泛型,可以接受任意类型。

二.? extends ...

这个是上界通配符,举个例子

//Lev 1
class Food{}

//Lev 2

class Fruit extends Food{}

class Meat extends Food{}

//Lev 3

class Apple extends Fruit{}

class Banana extends Fruit{}

class Pork extends Meat{}

class Beef extends Meat{}

//Lev 4

class RedApple extends Apple{}

class GreenApple extends Apple{}
Set<?extends Fruit> set1=new Set<Apple>();
Set<?extends Fruit> set2=new Set<Food>();//error

所以上界通配符代表着该容器可以接受存储着该类(extends 后面那个)及其类的容器

三.? super ...

下界通配符则与其刚好相反

Set<?super Fruit> set1=new Set<Apple>();//error
Set<?super Fruit> set2=new Set<Food>();

所以下界通配符代表着该容器可以接受存储着该类(extends 后面那个)及其类的容器

二.PECS原则的含义

很多人对PECS含糊不清,这里根本原因是对上下界通配符理解不够。要注意,上下界通配符是对于容器而言的,而PECS是对于容器中的数据类型而言的。

PECS 的全英是producer extends consumer super,意思是生产者extends,消费者super。

对于 ?extends Fruit来说,里面存储的数据类型一定是Fruit及其子类,那么使用Fruit类的变量来接收set是一定可以的,反之,将Fruit及其子类例如Apple存入反而可能不成立,因为万一这个范类对应的是YanTaiApple那就是将父类存入子类中!

class Apple extends Fruit{}
class YanTaiApple extends Apple{}
Set<? extends Fruit> set1= new Set<YanTaiApple>(new YanTaiApple());
Fruit fruit=set1.get(0);
set1.add(new Apple());//error

下界通配符原理类似,对于? super Fruit来说,里面存储的类型一定都是Fruit及其父类,那么我们如果将Apple和Banana存入是可以的,但是从set取的话,我们不能确定哪种类型能够存储它(Object当然可以,但是这样没有意义,因为它的属性我们会失去)

class Fruit extends Food{}
class Apple extends Fruit{}
class Banana extends Fruit{}
Set<? super Fruit> set=new Set<Fruit>();
set.add(new Apple());
set.get(0);//error
举报

相关推荐

0 条评论