相关文章推荐
1.https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java
2.https://howtodoinjava.com/java/generics/java-generics-what-is-pecs-producer-extends-consumer-super/
1.前言
为什么学习RxJava还要学习泛型?因为RxJava里面用到了大量的泛型,你能看懂吗?
为什么有得是extends 有得是supper 有的是T 有的是 ?接下来我们就来讲解下泛型的几种用法。
2.什么是PECS
讲到泛型就必须要讲到PECS(producer-extends-consumer-super)里面有生产者和消费者的概念。生产者使用extends 消费者使用super。
2.1 泛型的常见写法
1.extends (上界)
2.supper (下界)
3.T (指定类型)
4.? (通配符)
2.2 extends (只能读,不能写)
1.在传递的泛型类型可以是extends指定的子类,不能是父类型
2.在泛型种使用extends的时候不能写入需要传递泛型的数据,
下面举个例子
可以看到 这里我们使用了通配符<? extends String> 表示 可以传递的类型可以是String,以及他的子类型,但是由于这里我们是使用的extends,导致这里再使用add方法的时候无法将数据添加到list中,这个list已经不能被修改数据。
根据PECS法则里面提到,生产者是使用extends,消费者是super,因为这个list也是从外部传进来的,
所以如果使用了extends只能读取使用。就不要用作于修改数据了。
2.3 super (能写,不能完全读)
看个例子
2.4 T (类型参数)
一般用作与指定传递的类型或者指定返回的类型。常见的写法有用作于声明类的时候传递和在方法上进行传递 比如
class Response<T>{
int reponseCode;
String message;
T t; // 这个T表示返回你传入进来需要代表的对象
}
还有作用于方法上的用法
2.5 ? (通配符)
如果不确定需要传递的数据类型,则可以使用此通配符,如果确定了读写都是一样的数据类型,则可以不用此通配符。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBjNGaVo-1572847661209)(12.png)]
可以看到,这里使用通配符? 能够传递任意类型的数据进去,但是 取数的时候不能获取到真是的类型,如果想要获取到真实的类型可以像下面这样做。
3.总结
频繁往外读取内容的,适合用上界extends
经常往里写入数据的的,适合用下界super
如果您需要同时满足这两个条件,则不要使用任何通配符。
4.另外
数组是不安全的协变。建议尽量采用列表(List)的形式
例子
可以看到,这里是没有报错的,如果运行的话这里是发生异常的,这种异常在只有在运行的时候才能发现,到那个时候就已经太晚了。
Exception in thread "main" java.lang.ArrayStoreException: java.lang.String
at com.xiaxiayige.rxjavademo.generic.TestGeneric.main(TestGeneric.java:32)