LoginSignup
3
4

More than 5 years have passed since last update.

RxJava2のonNextでnullを使いたい

Posted at

RxJava2の変更点

こちらで紹介されているように、RxJava2では、onNextの引数にnullを渡すことができなくなっています。
元記事にもあるように、代替としてCompletableを利用することを勧めていましたが、これにはonNextがないので別の方法を検討します。

今回の開発環境

  • Android Studio
  • Kotlin
  • RxJava2

Kotlinの?(Optional)を自作OptionalでWrapする

Java8には、Optionalというクラスがあります。(参考:ここ
今回はこれを参考に、必要そうなメソッドを取り込んで自作のOptionalクラスを実装してみたいと思います。

コンストラクタ

コンストラクタは、

  • 中身がnullな場合
  • valueが存在する場合

の2パターンを実装しておけば良さそうなので、次のようにします。

Optional.kt
val value: T?

constructor() {
  this.value = null
}

constructor(value: T) {
  this.value = value
}

wrapper

↑このような表現が正しいかはさておき、引数をOptionalでwrapするメソッドを用意したいと思います。引数には、

  • T?な変数
  • Tな変数

のどちらかがくると思います。
もとのメソッド命名に合わせて、non-nullの場合にはof()、nullableの場合にはofNullable()と区別したいと思います。

Optional.kt
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()と区別することにします。

Optional.kt
fun get(): T {
  return value!!
}

fun getOrNull(): T? {
  return value
}

それっぽい完成品

ここまで説明した要素を合わせると、以下のようになると思います。

Optional.kt
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を使わないようなロジックに変更することを検討するべきなのでしょうが、どうしてもという場合には使えるかもしれないですね。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4