Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Kotlin辞典

lateinit / lazy

初期化を後回しにする『lateinit var』と、初回アクセス時に初期化する遅延プロパティ『by lazy』の仕組みです。

構文
// lateinit:後から初期化する変数(null非許容の var に使用)
lateinit var プロパティ名: 型

// by lazy:初回アクセス時に初期化する val
val プロパティ名: 型 by lazy {
    // 初期化処理
    値
}
構文一覧
構文概要
lateinit var 変数名: 型宣言時に初期化を省略できます。初期化前にアクセスすると例外が発生します。
::プロパティ名.isInitialized『lateinit』変数が初期化済みかどうかを確認します。
val 変数名 by lazy { }初回アクセス時にラムダが実行され、その結果が値として保存されます。
by lazy(LazyThreadSafetyMode.NONE) { }スレッドセーフを無効にした遅延初期化です。シングルスレッド用です。
サンプルコード
class DatabaseManager {
    // lateinit:後から代入するプロパティ
    lateinit var connectionString: String

    fun connect(url: String) {
        connectionString = url
    }

    fun status(): String {
        // isInitialized で初期化済みか確認できます。
        return if (::connectionString.isInitialized) {
            "接続済み: $connectionString"
        } else {
            "未接続"
        }
    }
}

class AppContext {
    // by lazy:初回アクセス時にだけ実行されます。
    val config: Map<String, String> by lazy {
        println("設定を読み込んでいます...")
        mapOf("theme" to "dark", "lang" to "ja")
    }
}

fun main() {
    val db = DatabaseManager()
    println(db.status())       // 未接続
    db.connect("jdbc://localhost")
    println(db.status())       // 接続済み: jdbc://localhost

    val ctx = AppContext()
    // 最初のアクセス時だけラムダが実行されます。
    println(ctx.config["theme"]) // 設定を読み込んでいます... → dark
    println(ctx.config["lang"])  // ラムダは実行されません → ja
}
概要

『lateinit var』はDIフレームワークやテストコードなど、コンストラクタ外で初期化が必要な場面で使います。初期化前にアクセスすると『UninitializedPropertyAccessException』が発生するため、不安な場合は『isInitialized』で確認してください。プリミティブ型(Int, Boolean など)には使えません。

『by lazy』は重い初期化処理を必要になるまで遅らせたいときに便利です。一度初期化されると値はキャッシュされ、以降はラムダが再実行されることはありません。デフォルトでスレッドセーフです。

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