lateinit
語法
不用一開始就要初始化變數,使用的時候,才初始化。
宣告一個非空(non-null)的變數,但不立即賦值,而是在之後的某個時間點再初始化。
使用時機:
用 lateinit:確定變數一定會被初始化,且只需要初始化一次
語法
private lateinit var 變數名: 類型
Android 的 ViewBinding
原本這樣寫會出錯,強迫一定要初始化
1
private var binding : ActivityMainBinding
在var前面加上lateinit延後初始化,就不用一開始就一定要初始化。
1
private lateinit var binding : ActivityMainBinding
沒加lateinit,又不設預設值,會編譯錯誤。
1
2
3
4
5
6
7
class MyActivity : AppCompatActivity() {
// 編譯錯誤:必須在構造函式中初始化
private var binding: ActivityMainBinding
// 但這樣寫很醜,要用 null 和 !!
private var binding: ActivityMainBinding? = null
}
完整初始化程式碼
1
2
3
4
5
6
7
8
9
10
class MainActivity13 : AppCompatActivity() {
// 延後初始化
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 在這初始化
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
類別成員變數
判斷是否有初始值
::變數.isInitialized
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyClass {
lateinit var retrofit: String
fun init() {
retrofit = "retrofit is ready!"
}
fun use() {
if (::retrofit.isInitialized) {
println(retrofit)
}
}
}
fun main() {
val myclass = MyClass()
myclass.init()
myclass.use()
}
retrofit is ready!
不能用 lateinit 的情況
基本類型不能用lateinit,會編譯錯誤。
1
2
3
lateinit var count: Int
lateinit var price: Double
lateinit var isInit: Boolean
可空類型不能用lateinit
1
lateinit var name: String?
建構子也不能用lateinit
1
2
class MyClass(lateinit var name: String) {
}
可空類型 vs lateinit
可空類型,使用前要用 ? 或 .let{} 判斷是否為null。
1
2
3
4
5
6
7
8
9
10
class MyClass2() {
var name: String? = null
fun init() {
name = "Bill"
}
fun use() {
println(name?.length ?: 0)
}
}
lateinit,使用時不用加 ?
1
2
3
4
5
6
7
8
9
10
class MyClass2() {
lateinit var name: String
fun init() {
name = "Bill"
}
fun use() {
println(name.length)
}
}