泛型的简介
泛型的使用
泛型类和泛型接口
泛型的实质:
允许在定义接口、类时声明类型形参,类型形参在整个接口、类体内可当成类型使用,几乎所有可使用普通类型的地方都可以使用这种类型形参。
//定义接口时指定了一个类型形参,该形参名为E
public interface List<E> extends Collection<E> {
//在该接口里,E可以作为类型使用
public E get(int index) {
}
public void add(E e) {
}
}
//定义类时指定了一个类型形参,该形参名为E
public class ArrayList<E> extends AbstractList<E> implements List<E> {
//在该类里,E可以作为类型使用
public void set(E e) {
//TODO ...
}
}
泛型类
public class Container<K, V> {}
泛型类派生子类
正确的方式:
public class A extends Container<Integer, String>{}
也可以不指定具体的类型,如下:
public class A extends Container{}
此时系统会把K,V形参当成Object类型处理。
泛型的方法
修饰符<T, S> 返回值类型 方法名(形参列表){
方法体
}
注意:方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。
泛型构造器
一种是显式指定泛型参数,另一种是隐式推断。
类型通配符
类型通配符是一个问号(?)
带限通配符
使用通配符的目的是来限制泛型的类型参数的类型,使其满足某种条件,固定为某些类。
上限通配符extends
如果想限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口,也可以是这个类或接口本身。
//它表示集合中的所有元素都是Shape类型或者其子类
List<? extends Shape>
这就是所谓的上限通配符,使用关键字extends来实现,实例化时,指定类型实参只能是extends后类型的子类或其本身。
//Circle是Shape子类
List<? extends Shape> list = new ArrayList<Circle>();
这样就确定集合中元素的类型,虽然不确定具体的类型,但最起码知道其父类。然后进行其他操作。
下限通配符super
如果想限制使用泛型类别时,只能用某个特定类型或者是其父类型才能实例化该类型时,可以在定义类型时,使用super关键字指定这个类型必须是是某个类的父类,或者是某个接口的父接口,也可以是这个类或接口本身。
//它表示集合中的所有元素都是Circle类型或者其父类
List <? super Circle>
这就是所谓的下限通配符,使用关键字super来实现,实例化时,指定类型实参只能是extends后类型的子类或其本身。
//Shape是其父类
List<? super Circle> list = new ArrayList<Shape>();
RxJava中的应用
RxJava是最经典的泛型应用了吧
这个map的处理实在是精髓所在
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <R> Observable<R> map(Function<? super T, ? extends R> mapper) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new ObservableMap<T, R>(this, mapper));
}
上限下限模式---读写模式
什么时候是上限下限模式?
方法中以泛型参数的形式存在时候
什么时候是读写模式?
真正使用到泛型的时候
Observable2.create(new ObservableOnSubscribe2<Integer>() {
@Override
public void subscribe(Observer2<? super Integer> emitter) {
emitter.onNext(10);
emitter.onComplete();
}
}).
其中 subscribe(Observer2<? super Integer> emitter)中的emitter 用到了,
所以这里要调用emitter.onNext(10);的话就要用到super.
? super T--> 下限:T or T
所有父类,都可以,所以属于把下面的类型给限制了,下面的类型不能低于T,不能是T的子类,否则编译不通过.
? super T--> 可写不完全可读
? extends R --> 上限:R or R
所有子类,都可以,所以属于把上面的类型给限制了,上面的类型不能高于R,不能是R的父类,否则编译不通过.