Middle
Jaka jest różnica między używaniem słowa kluczowego 'lateinit' a delegowaniem za pomocą 'by lazy {}' w Kotlin?
sobes.tech AI
Odpowiedź od AI
lateinit jest używany do opóźnionej inicjalizacji zmiennych właściwości (var), które nie mogą być nullable i będą inicjalizowane później, na przykład w metodzie cyklu życia aktywności lub fragmentu. Kompilator nie gwarantuje inicjalizacji, a dostęp do niezainicjalizowanej właściwości spowoduje wyjątek UninitializedPropertyAccessException.
by lazy {} jest używany do opóźnionej inicjalizacji właściwości niezmiennych (val). Inicjalizacja odbywa się przy pierwszym dostępie do właściwości, a wynik jest buforowany. Domyślnie jest to bezpieczne wątkowo i gwarantuje, że inicjalizator zostanie wywołany tylko raz.
| Cecha | lateinit |
by lazy {} |
|---|---|---|
| Dotyczy | var |
val |
| Nullable | Nie nullable | Nie nullable |
| Gwarancja inicjalizacji | Nie (tylko przez programistę) | Tak (przy pierwszym dostępie) |
| Bezpieczeństwo wątków | Nie gwarantowane domyślnie | Tak (domyślnie) |
| Typ właściwości | Zmienny | Niezmienny |
Przykład z 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 = "Witaj, lateinit!"
}
}
Przykład z by lazy {}:
class MyViewModel : ViewModel() {
private val apiService: ApiService by lazy { provideApiService() } // Inicjalizacja przy pierwszym użyciu
private fun provideApiService(): ApiService {
// Logika tworzenia ApiService
return ApiService()
}
fun fetchData() {
// apiService jest inicjalizowany tutaj przy pierwszym wywołaniu fetchData()
apiService.getData()
}
}