Kotlinで関数の引数などの条件をチェックする関数

kotlinの標準ライブラリに条件式を満たさなければ例外を出すという動作を行う関数が定義されています。
関数内で引数の条件をチェックする場合などに使うと便利なので紹介したいと思います

IllegalArgumentExceptionを発生させる

引数をチェックするための関数は以下の4つがあります

  • fun require(value: Boolean)
  • fun require(value: Boolean, lazyMessage: () -> Any)
  • fun requireNotNull(value: T?): T
  • fun requireNotNull(value: T?, lazyMessage: () -> Any): T

使用例

fun require(value: Boolean)

fun List<String>.second() {
    require(size >= 2)
    this[1]
}

listOf("a").second()
// => java.lang.IllegalArgumentException: Failed requirement.

fun require(value: Boolean, lazyMessage: () -> Any)
こちらは、例外を投げる時のメッセージを指定することが可能です

fun List<String>.second() {
    require(size >= 2){
        if(size==0) "リストの要素が1つも無いよ"
        else "リストの要素が1つしかないよ"
    }
    this[1]
}

listOf("a").second()
// => java.lang.IllegalArgumentException: リストの要素が1つしかないよ

fun requireNotNull(value: T?): T

fun f(v: Any?): String {
    requireNotNull(v)
    return v.toString()
}

f(null)
// => java.lang.IllegalArgumentException: Required value was null.

f("not null")
// => "not null"

fun requireNotNull(value: T?, lazyMessage: () -> Any): T

fun f(v: Any?): String {
    requireNotNull(v){ "nullじゃない値がほしい" }
    return v.toString()
}

f(null)
// => java.lang.IllegalArgumentException: nullじゃない値がほしい

IllegalStateExceptionを発生させる

なんらかの処理を行う前に関係する状態をチェックするための関数が定義されています

  • fun check(value: Boolean)
  • fun check(value: Boolean, lazyMessage: () -> Any)
  • fun checkNotNull(value: T?): T
  • fun checkNotNull(value: T?, lazyMessage: () -> Any): T

使用例

関数の使い方はrequireとほとんど同じなので1つだけ例をあげておきます

var someState: String? = null
fun end(): String {
    val state = checkNotNull(someState) { "Stateがnullになっている" }
    check(state == "start") { "この処理を実行するにはStateがstartの必要があります" }
    // ...
    return state
}

someState="end"
end()
// => java.lang.IllegalStateException: この処理を実行するにはStateがstartの必要があります

まとめ

requireやcheck関数を使用することで特定の状況でのみ処理が実行されることを保証することができるため、バグを生みにくくコードが読みやすくなることが期待できます。
requireとcheck関数の処理や呼び出し方法はほとんど変わらないため、場面に応じて使い分けると良いでしょう。