如何使用RxJava2 Maybe实现Repository Pattern?空指针问题求助
解决RxJava2中Maybe结合Repository Pattern的NullPointerException问题
我太懂这种感受了——本来想摆脱繁琐的空容器类,用Maybe简化Repository的空值处理,结果反而踩了NullPointerException的坑,着实头疼!
问题根源
你遇到的NPE,本质是RxJava2的设计规范导致的:Maybe.just()方法不允许传入null值。一旦cacheDataHelper.getFoo()返回null,Maybe.just(null)会直接抛出空指针异常,而不是优雅地处理空情况。
两种可行的解决方案
方案1:用Maybe.fromCallable()延迟执行并自动处理null
这是最简洁的方式,fromCallable()会在订阅时才执行你的数据获取逻辑,并且如果返回null,它会自动让Maybe触发onComplete()(不发射任何数据),完全避免NPE:
protected Maybe<Foo> loadDataFromCache() { return Maybe.fromCallable(() -> cacheDataHelper.getFoo()); }
方案2:手动判空,返回Maybe.empty()
如果更倾向于显式控制逻辑,可以先获取数据,判断不为null时用Maybe.just()发射,否则返回空的Maybe:
protected Maybe<Foo> loadDataFromCache() { Foo foo = cacheDataHelper.getFoo(); return foo != null ? Maybe.just(foo) : Maybe.empty(); }
结合Repository Pattern的典型用法
解决了缓存的空值问题后,你可以这样组合缓存+网络的逻辑,完美契合Repository模式:
public Single<Foo> getFoo() { return loadDataFromCache() // 缓存为空时,切换到网络请求 .switchIfEmpty(loadDataFromNetwork() // 网络请求成功后,把数据存入缓存 .doOnSuccess(foo -> cacheDataHelper.saveFoo(foo))) // 转成Single,给上层调用者统一的返回类型 .toSingle(); }
这里switchIfEmpty()会在缓存的Maybe没有发射数据时,自动执行网络请求的逻辑,既保证了性能(优先读缓存),又简化了空值处理,完全不用额外的空容器类。
内容的提问来源于stack exchange,提问作者Bin Fan




