Назад к вопросам
Middle
72
questionbank

В чем разница между использованием ключевого слова 'lateinit' и делегирования с помощью 'by lazy {}' в Kotlin?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

lateinit используется для отложенной инициализации изменяемых свойств (var), которые не могут быть nullable и будут инициализированы позже, например, в методе жизненного цикла активности или фрагмента. Компилятор не гарантирует инициализацию, и доступ к неинициализированному свойству вызовет исключение UninitializedPropertyAccessException.

by lazy {} используется для отложенной инициализации неизменяемых свойств (val). Инициализация выполняется при первом доступе к свойству, и результат кешируется. Это потокобезопасно по умолчанию и гарантирует, что инициализатор будет вызван только один раз.

Признак lateinit by lazy {}
Применяется к var val
Nullability Не 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 = "Hello, 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()
    }
}