alwaystest / Blog

24 stars 2 forks source link

RxJava与泛型 #41

Open alwaystest opened 7 years ago

alwaystest commented 7 years ago

RxJava与泛型

标签(空格分隔): Android RxJava


使用RxJava改造旧有的网络请求,在BaseRequest中添加一个方法,直接设置响应的Listener,在onResponse的时候调用subscriber.onNext(response),在onError的时候调用subscriber.onError(new Throwable(errMsg))。

用到泛型定义 返回值类型的时候,发现一个奇怪的问题。

Observable.create(new Observable.OnSubscribe<ExpectedClass>() {
    @Override
    public void call(final Subscriber<? super ExpectedClass> subscriber) {
        subscrober.onNext(new Object());
        }
    })

这样写的话语法检查会报错:Capture<? super ExpectedClass> can not be applied to java.lang.Object

于是我就很奇怪,按照<? super ExpectedClass>的语法,Object是ExpectedClass的父类,应该是合法的。

尝试把报错的代码改为以下是不会报错的

Observable.create(new Observable.OnSubscribe<ExpectedClass>() {
    @Override
    public void call(final Subscriber<? super ExpectedClass> subscriber) {
        subscrober.onNext(new SubExpectedClass()); //SubExpectedClass extends ExpectedClass
        }
    })

于是我简直要怀疑IDE了。

网上查找后我发现了张光光的文章,总算解决了我的疑惑。建议通读全文,打实基础。

但是这里和存东西取东西又有区别。

个人猜测是这样子理解的,将来看懂RxJava源码以后再补坑为什么RxJava要这样子设计。以下代码纯属伪代码,方便理解就行了,不要自行车。

Subccriber<? super ExpectedClass> 定义了一个容器,这个容器可以是存放ExpectedClass的父类的容器,这样就可以保证这个容器中可以装得下ExpectedClass对象。

来看看RxJava中的定义

public interface Observable<T> {
    void onNext(T t);
    ...
}

对应的使用是这样的

Observable.create(new Observable<ExpectedClass>() {
    @Override
    public void call(final Observabler<? super ExpectedClass> subscriber) {
        subscrober.onNext(new SubExpectedClass()); //SubExpectedClass extends ExpectedClass
        }
    })

按照容器的理论来理解, subscriber可以是Observable<SuperExpectedClass>,这个时候:

  1. onNext(new SubExpectedClass())是符合语法的, 因为SubExpectedClass也是SuperExpectedClass
  2. onNext(new SuperSuperExpectedClass())就不符合语法了,因为SuperSuperExpectedClass不是SuperExpectedClass

所以尽管call(final Observabler<? super ExpectedClass> subscriber)定义使用了super,subscrober.onNext(new SuperSuperExpectedClass())却是不合法的。

我个人觉得举例子如果举不好,不如不举例。不知道我上面的例子是不是容易理解。欢迎反馈。