[Kotlin]遅延初期化(latinit,lazy)
💡 遅延初期化とは?
一般に、
1. Late initialization varの前にlatinitキーワードを使用して宣言します. クラスの内部変数またはトップレベル、地域変数として使用できます. non-nullタイプのみが許可され、元のタイプは使用できません. を初期化しないとExceptionが表示されます. lateinit property string has not been initialized latinit varを初期化するかどうか
初期化の有無を確認するには、 valでのみ使用可能で、by lazyを使用して宣言します. 最初の呼び出し実行はbylazyのramdaに渡され、結果値が保存されます. のデフォルトでは、値は1つのスレッドでのみ計算され、すべてのスレッドに同じ値が表示されます.
ふかっせいないぶコード
get()呼び出しの場合、
その後、synchronizedを使用してスレッドのセキュリティを確保し、
🙏 の最後の部分
特定の時点で
📜 リファレンス Late-initialized properties and variables Lazy properties Kotlin lazy property-latinit/lazy表示
一般に、
propertie
をnon-null type
と宣言するには、ジェネレータで初期化する必要がある.ただし、コンストラクション関数が初期化できない場合、またはnull type
を回避したい場合は、使用時に初期化するための遅延初期化(Late Initialization,Lazy Initialization)を提供します.1. Late initialization
lateinit var string: String
初期化の有無を確認するには、
property
の前に::
キーワードを使用して.isInitialized
を呼び出す.class LateInitTest {
latinit var string: String
@Test
fun test() {
// println(string) // Exception
if (!::string.isInitialized) {
string = "init"
}
println(string)
}
}
2. Lazy initializationval string: String by lazy { "init" }
class LazyTest {
val lazyValue: String by lazy {
println("computed!")
"Hello"
}
@Test
fun test() {
println(lazyValue)
println(lazyValue)
}
}
computed!
Hello
Hello
上記の出力結果を表示すると、プログラムが最初にアクセスしたときにram式が呼び出され、ram式の結果値が返されます.ふかっせいないぶコード
private class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>, Serializable {
private var initializer: (() -> T)? = initializer
@Volatile private var _value: Any? = UNINITIALIZED_VALUE
// final field is required to enable safe publication of constructed instance
private val lock = lock ?: this
override val value: T
get() {
val _v1 = _value
if (_v1 !== UNINITIALIZED_VALUE) {
@Suppress("UNCHECKED_CAST")
return _v1 as T
}
return synchronized(lock) {
val _v2 = _value
if (_v2 !== UNINITIALIZED_VALUE) {
@Suppress("UNCHECKED_CAST") (_v2 as T)
} else {
val typedValue = initializer!!()
_value = typedValue
initializer = null
typedValue
}
}
}
override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE
override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."
private fun writeReplace(): Any = InitializedLazyImpl(value)
}
内部コードでは、最初の_value
がUNITIALIZED VALUE(internal object UNINITIALIZED_VALUE
)に初期化される.get()呼び出しの場合、
_value
がUNITIALIZED VALUEでない場合、_value
を返します.その後、synchronizedを使用してスレッドのセキュリティを確保し、
_value
がUNITIAZED VALUEであるかどうかを再確認し、UNITIAZED VALUEである場合、ram式を呼び出して結果値を保存し、戻ります.🙏 の最後の部分
lateinit
はコンストラクション関数では初期化できませんが、non-null
を使用する場合は特定の時点で初期化し、value
を変更し続ける必要がある場合は使用します.特定の時点で
lazy
を初期化したい場合は、最初のアクセス時にvalue
を初期化し、後でvalue
を変更する必要がない場合は使用します.📜 リファレンス
Reference
この問題について([Kotlin]遅延初期化(latinit,lazy)), 我々は、より多くの情報をここで見つけました https://velog.io/@haanbink/Kotlin-지연초기화lateinit-lazyテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol