言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Kotlin辞典

  1. トップページ
  2. Kotlin辞典
  3. !! 非nullアサーション

!! 非nullアサーション

対応: Kotlin 1.0(2016)

Kotlinの『!!』(非nullアサーション演算子)は、Nullable型の値をnon-null型として扱う演算子です。値がnullの場合は『NullPointerException』がスローされます。

構文

// !! 演算子で Nullable 型を non-null 型に変換する
val name: String? = "item_x"
val length: Int = name!!.length // String? → String として扱う

// null の場合は NullPointerException がスローされる
val nullValue: String? = null
val len = nullValue!!.length // 例外スロー

構文一覧

構文概要
value!!null でなければ non-null 型として返します。null なら NullPointerException をスローします。
value!!.method()null チェックなしでメソッドを呼び出します。null なら例外がスローされます。
value!!.propertynull チェックなしでプロパティにアクセスします。

サンプルコード

sample_non_null_assertion.kt
// !! 演算子のデモ
fun getUser(id: Int): String? = if (id > 0) "User-$id" else null

fun main() {
    // null でない場合は正常に動作する
    val name: String? = "item_x"
    println(name!!.length) // 6
    println(name!!.uppercase()) // ITEM_X

    // スマートキャストが使えない外部関数の結果に使う例
    val user = getUser(1)!! // null でないことが分かっている場合
    println("ユーザー: $user") // ユーザー: User-1

    // !! を使わない安全な代替手法との比較
    val nullable: String? = "Kotlin"

    // 方法1: !! (nullなら例外)
    println(nullable!!.length) // 6

    // 方法2: ?.let(安全)
    nullable?.let { println(it.length) } // 6

    // 方法3: ?: (nullなら代替値)
    println(nullable?.length ?: 0) // 6

    // null の場合に !! を使うと例外が発生する
    try {
        val nullStr: String? = null
        println(nullStr!!.length) // ここで例外
    } catch (e: NullPointerException) {
        println("例外キャッチ: ${e::class.simpleName}") // NullPointerException
    }
}

コンパイルして実行すると次のようになります。

kotlinc sample_non_null_assertion.kt -include-runtime -d sample_non_null_assertion.jar
java -jar sample_non_null_assertion.jar
6
ITEM_X
ユーザー: User-1
6
6
6
例外キャッチ: NullPointerException

よくあるミス

sample_non_null_assertion_mistakes.kt
fun getUserName(id: Int): String? = if (id > 0) "item_x" else null

fun main() {
    // null になりうる値に !! を使う
    val name: String? = null
    println(name!!.length) // NullPointerException がスローされる

    // !! を連鎖させる
    val user: String? = getUserName(-1)
    println(user!!.trim()!!.uppercase()) // 2 箇所で NullPointerException の危険がある

    // !! でキャッチしたつもりが例外型を間違える
    try {
        val nullStr: String? = null
        println(nullStr!!.length)
    } catch (e: KotlinNullPointerException) { // Kotlin 1.4 以降は NullPointerException
        println("キャッチできない")
    }
}

コンパイルして実行すると次のようになります。

kotlinc sample_non_null_assertion_mistakes.kt -include-runtime -d sample_non_null_assertion_mistakes.jar
java -jar sample_non_null_assertion_mistakes.jar
Exception in thread "main" java.lang.NullPointerException

概要

『!!』演算子はKotlinのNull安全機能をバイパスするため、null以外であることが確実な場面で使われます。プロダクションコードでは『?.』演算子や『?:』エルビス演算子、『?.let』による安全な代替手法と使い分ける傾向があります。

注意: nullが入る可能性がある箇所で『!!』を使うと NullPointerException が発生します。代わりに『?.』演算子や『?:』エルビス演算子、『?.let』を検討してください。

Nullable型の基本はNullable 型 / ?. 演算子を、デフォルト値の設定には?: エルビス演算子を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。