RxJava2の変更点
こちらで紹介されているように、RxJava2では、onNext
の引数にnullを渡すことができなくなっています。
元記事にもあるように、代替としてCompletable
を利用することを勧めていましたが、これにはonNext
がないので別の方法を検討します。
今回の開発環境
- Android Studio
- Kotlin
- RxJava2
Kotlinの?(Optional)を自作OptionalでWrapする
Java8には、Optional
というクラスがあります。(参考:ここ)
今回はこれを参考に、必要そうなメソッドを取り込んで自作のOptionalクラスを実装してみたいと思います。
コンストラクタ
コンストラクタは、
- 中身がnullな場合
- valueが存在する場合
の2パターンを実装しておけば良さそうなので、次のようにします。
val value: T?
constructor() {
this.value = null
}
constructor(value: T) {
this.value = value
}
wrapper
↑このような表現が正しいかはさておき、引数をOptional
でwrapするメソッドを用意したいと思います。引数には、
-
T?
な変数 -
T
な変数
のどちらかがくると思います。
もとのメソッド命名に合わせて、non-nullの場合にはof()
、nullableの場合にはofNullable()
と区別したいと思います。
companion object {
fun <T> of(value: T): Optional<T> {
return Optional(value)
}
fun <T> ofNullable(value: T?): Optional<T> {
return if(value != null) Optional(value) else Optional()
}
}
今回はKotlinの場合なので、companion object
内に実装します。
Javaならstatic
メソッドですね。
getter
これも以下のパターンが考えられます。
-
T
というようにnullを許容しない場合 -
T?
というようにnullを許容する場合
前者はget()
で、後者はgetOrNull()
と区別することにします。
fun get(): T {
return value!!
}
fun getOrNull(): T? {
return value
}
それっぽい完成品
ここまで説明した要素を合わせると、以下のようになると思います。
class Optional<T> {
private val value: T?
private constructor() {
this.value = null
}
private constructor(value: T) {
this.value = value
}
fun get(): T {
return value!!
}
fun getOrNull(): T? {
return value
}
companion object {
fun <T> of(value: T): Optional<T> {
return Optional(value)
}
fun <T> ofNullable(value: T?): Optional<T> {
return if (value != null) Optional(value) else Optional()
}
}
}
使ってみる
早速、問題の部分に作成したOptional
クラスを適用してみます。
Websocketから拾ったメッセージをPublishSubject
に流す部分です。
override fun onMessage(webSocket: WebSocket?, text: String?) {
//responseのjson->objectに変換
val res: WsResponse? = gson.fromJson(text, WsResponse::class.java)
//エラーでるパターン
wsSocketEventSerialized.onNext(res)
//Optionalでwrapしてみる
wsSocketEventSerialized.onNext(Optional.ofNullable(res))
本来ならば、null
が来ないようにするとか、null
を使わないようなロジックに変更することを検討するべきなのでしょうが、どうしてもという場合には使えるかもしれないですね。