Middle
Qual è la differenza tra l'utilizzo della parola chiave 'lateinit' e la delega con 'by lazy {}' in Kotlin?
sobes.tech AI
Risposta dell'AI
lateinit viene utilizzato per l'inizializzazione differita delle proprietà mutabili (var) che non possono essere null e saranno inizializzate più tardi, ad esempio nel metodo del ciclo di vita di un'attività o di un frammento. Il compilatore non garantisce l'inizializzazione, e l'accesso a una proprietà non inizializzata causerà un'eccezione UninitializedPropertyAccessException.
by lazy {} viene usato per l'inizializzazione differita delle proprietà immutabili (val). L'inizializzazione avviene al primo accesso alla proprietà, e il risultato viene memorizzato nella cache. Questo è thread-safe di default e garantisce che l'inizializzatore venga chiamato una sola volta.
| Caratteristica | lateinit |
by lazy {} |
|---|---|---|
| Applicabile a | var |
val |
| Nullabilità | Non nullable | Non nullable |
| Garanzia di inizializzazione | No (solo dallo sviluppatore) | Sì (al primo accesso) |
| Sicurezza thread | Non garantito di default | Sì (di default) |
| Tipo di proprietà | Mutabile | Immutabile |
Esempio con 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 = "Ciao, lateinit!"
}
}
Esempio con by lazy {}:
class MyViewModel : ViewModel() {
private val apiService: ApiService by lazy { provideApiService() } // Inizializzazione al primo utilizzo
private fun provideApiService(): ApiService {
// Logica di creazione di ApiService
return ApiService()
}
fun fetchData() {
// apiService viene inizializzato qui alla prima chiamata a fetchData()
apiService.getData()
}
}