泛型总结
前言
在新公司看后台封装的分页查询,然后接触到了泛型,虽然知道,但并没有很好的理解其用法,自己平常也没用过,所以研究了一下,下面主要讲解一下上界通配符<? extends T>和下届通配符<? super T>这两种类型。
一、上界通配符<? extendsT>(Upper Bounds Wildcards)
1.首先?表示为T的子类,从字面上也可以看出,extends继承了T,所以?为子类。
2.其的功能是可以取出,但不能放入
比如,我们有盘子plate这个类,也有fruit和appale这三个类
1.Plate是泛型
public class Plate<T> {
private T item;
public Plate(Titem) {
this.item = item;
}
public TgetItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
}
2.下面是测试类
Plate <? extends Fruit> p=new Plate<Apple>(new Apple());
p.set(new Fruit());//上界通配符的set方法失效了Error
p.set(new Fruit());//Error
//取出来的值会放在Fruit或他的基类里
Apple apple=p.get();//Error
Fruit fruit=p.get();
Object object=p.get();
(1)由于编译器只知道这个容器里面需要放入Fruit类或者他的派生类,但具体是什么类型不知道可能是Fruit或者appale,banner等,但赋值以后,比如Plate<Appale>,盘子里没有appale类型,只是用了一个占位符CAP#1,在放入Appale以后发现与CAP#1不匹配,所以就set不进去。
(2)从这个里面也可以看出,在获取appale时,需要强转才能获取到,同样的原因,plate里面只放了Fruit类或者他的派生类,取不出其他的东西。
二、下界通配符<? superT>(Lower Bounds Wildcards)
1.?表示T的父类。
2.不影响往里存东西,但是取的东西只能放到Object类里。
(1)test类
Plate<? super Fruit> plate=new Plate<Fruit>(new Fruit());
plate.set(new Fruit());plate.set(new Apple());
Apple apple1= plate.get();//Error
Fruit fruit1= plate.get();//Error
Object object=plate.get();
(2)从上面可以看出在set时没有报错,但在get时报错了。是因为?是Fruit或其子类,都能存入,?是Fruit的父类,所以比Fruit小的都可以。但取的时候只能其他类的基类Object,这样会丢失很多属性。
三、使用原理
那我们在使用的时候该怎么用呢,下面介绍一种选择方法PECS原则。
1.PECS(ProducerExtends Consumer Super)
(1)频繁往里取内容的时候,用上界通配符
(2)经常往里插内容时,用下界通配符
本人感觉这两句话有点多余,知道原理以后,就知道什么情况下可以用。