在 Kotlin 中使用 Lazy 和 Lateinit 初始化屬性
本文介紹了幫助初始化屬性的 lazy()
和 lateinit
的 Kotlin。我們將從瞭解這些屬性初始化器的作用開始,然後瞭解兩者之間的區別。
如果我們想在建構函式之外或類體底部的某個地方初始化一個屬性,我們只有兩個選擇:延遲初始化或 lateinit
。
在 Kotlin 中使用 by lazy
初始化屬性
延遲初始化是在 lazy()
函式的幫助下完成的。它接受一個 lambda 作為輸入並返回一個 lazy<t>
的例項。
該例項用於實現惰性屬性所需的委託。預設情況下,惰性屬性的評估是同步的。
同步意味著儘管編譯器在單個執行緒中計算值,但所有執行緒將看到相同的值。
Kotlin 允許使用 LazyThreadSafetyMode.PUBLICATION
作為 lazy()
函式的引數來防止同步。
例子:
val lazyVal: String by lazy {
println("This is an")
"example of lazy initialization!"
}
fun main() {
println(lazyVal)
}
輸出:
在 Kotlin 中使用 lateinit
初始化屬性
後期初始化允許在建構函式之外初始化非空型別屬性,同時避免空檢查。
通常,非空屬性在建構函式中初始化。但是在某些情況下,我們可能希望不這樣做,例如設定單元測試方法。
lateinit
修飾符有助於解決此類問題。我們可以將此初始化程式與 var
或可變屬性一起使用。
關於 lateinit
修飾符需要記住的幾點是:
- 我們可以在主建構函式之外使用
lateinit
- 我們只能將
lateinit
用於沒有自定義getters()
和setters()
的屬性。 - 屬性的型別應該是非空的和原始的
例子:
lateinit var student1:Student
fun main(args: Array<String>) {
student1 = Student("David Henry's",303)
print(student1.Name + " ID is " + student1.ID.toString())
}
data class Student(var Name:String, var ID:Int);
輸出:
Kotlin 中 by lazy
和 lateinit
的區別
by lazy
和 lateinit
修飾符之間存在幾個顯著差異。這裡是其中的一些:
by lazy
用於初始化val
屬性,lateinit
用於初始化var
屬性。lateinit
使用支援欄位來儲存結果的值,by lazy
使用委託物件。- 我們不能將
lateinit
與可空屬性或 Java 原始型別一起使用。 - 我們可以從編譯器可以看到物件的任何地方初始化
lateinit
並支援多個初始化。另一方面,by lazy
只允許進行一次初始化,該初始化只能通過覆蓋子類中的屬性來更改。 by lazy
初始化預設是執行緒安全的,lateinit var
修飾符跨多個執行緒的初始化取決於使用者的程式碼。- 我們可以為多個屬性儲存、傳遞甚至使用
by lazy
初始化程式的例項。但是lateinit
中沒有額外的執行時狀態。
在 Kotlin 中何時使用 by lazy
我們可以使用 by lazy
時,
- 我們不希望變數初始化,除非我們呼叫或使用它們;
- 我們想初始化一個變數,然後在整個程式碼中使用它;和
- 我們正在使用只讀屬性。
在 Kotlin 中何時使用 lateinit
我們可以在以下情況下使用 lateinit
,
- 我們要延遲初始化一個變數;
- 我們想在使用它之前初始化一個變數;
- 我們正在使用
var
或可變屬性;和 - 變數可能會在稍後階段發生變化。
Kailash Vaviya is a freelance writer who started writing in 2019 and has never stopped since then as he fell in love with it. He has a soft corner for technology and likes to read, learn, and write about it. His content is focused on providing information to help build a brand presence and gain engagement.
LinkedIn