Kotlin'de geç bir başlatma için iki farklı yaklaşım vardır: lateinit ve lazy.
lateinit — Daha sonra başlatılacak değişkenlere (var) uygulanabilen bir modifikatördür, genellikle DI veya başlatma bloğu aracılığıyla. Sadece statik olmayan nullable olmayan değiştirmezler için uygundur. Başlatmadan önce erişim, UninitializedPropertyAccessException istisnasını atar.
class MyClass { lateinit var data: String fun init() { data = "Merhaba!" } }
lazy — yalnızca okunabilir (read-only) val özelliklerine uygulanan özel bir delegedir. Başlatma ifadesi, değişkene ilk erişimde hesaplanır. Varsayılan olarak çok iş parçacıklı erişim için güvenlidir.
val config: Config by lazy { loadConfigFromFile() }
lateinit, ilkel türlerle ve val ile çalışmaz.lazy, yeniden başlatmaya izin vermez.lateinit, daha sonra atanacağı garantilenen değişkenler için (örneğin, bir DI çerçevesi aracılığıyla veya bir Android yaşam döngüsü parçasında) kullanılmalıdır.lazy, değer hesaplama açısından maliyetliyse ve gerekilmeyebiliyorsa tembel hesaplamalar için kullanılmalıdır.Int türündeki özellikler için
lateinitkullanabilir miyiz?
Yanıt: Hayır. lateinit, yalnızca nesne olan nullable olmayan türlerle çalışır. İlkel türler ve nullable türler için kullanılamaz. lateinit var a: Int ifadesini kullanmaya çalışmak derleme hatasına yol açar.
Hikaye
Eğitim projesinde yapılandırma değişkeni lateinit var config: Config? olarak tanımlandı, ancak derleyici bunu yapmayı kabul etmedi — zaman kazandılar ama neden bekledikleri gibi çalışmadığını anlamak zorunda kaldılar.
Hikaye
Bir Android uygulamasında lateinit özelliğinin başlatılmadan önce kontrol edilmesi unutuldu. Bu, uygulamanın prod'da çökmesine neden oldu — tasarımcı, onCreateView'den önce özelliğe erişmeye çalıştı. Ek kontrol ile yardımcı oldular.
Hikaye
Çok iş parçacıklı kullanırken geliştirici, parametre vermeden kaynak yoğun bir nesneyi başlatmak için by lazy kullandı, varsayılan delegenin çok iş parçacıklı güvenli olmadığını düşündü. Sonuç olarak, sürümde yarış durumu sorunlarıyla karşılaştık. by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { ... } şeklinde uygun parametre geçirerek çözdüler.