Middle
Каква е разликата между използването на ключовата дума 'lateinit' и делегирането с 'by lazy {}' в Kotlin?
sobes.tech AI
Отговор от AI
lateinit се използва за отложена инициализация на променливи свойства (var), които не могат да бъдат nullable и ще бъдат инициализирани по-късно, например в метода на жизнения цикъл на активност или фрагмент. Компилаторът не гарантира инициализация, и достъпът до неинициализирано свойство ще предизвика изключение UninitializedPropertyAccessException.
by lazy {} се използва за отложена инициализация на неизменяеми свойства (val). Инициализацията се извършва при първия достъп до свойството, и резултатът се кешира. Това е по подразбиране потокобезопасно и гарантира, че инициализаторът ще бъде извикан само веднъж.
| Характеристика | lateinit |
by lazy {} |
|---|---|---|
| Приложимо към | var |
val |
| Nullable | Не nullable | Не nullable |
| Гаранция за инициализация | Не (само от разработчика) | Да (при първия достъп) |
| Потокобезопасност | Не гарантирано по подразбиране | Да (по подразбиране) |
| Тип на свойството | Модифицирано | Неизменяемо |
Пример с lateinit:
class MyActivity : AppCompatActivity() {
private lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.my_text_view)
textView.text = "Здравей, lateinit!"
}
}
Пример с by lazy {}:
class MyViewModel : ViewModel() {
private val apiService: ApiService by lazy { provideApiService() } // Инициализация при първо използване
private fun provideApiService(): ApiService {
// Логика за създаване на ApiService
return ApiService()
}
fun fetchData() {
// apiService се инициализира тук при първия извикване на fetchData()
apiService.getData()
}
}