परिचय
`lateinit` मॉडिफायर non-null वेरिएबल्स के डिफर्ड इनिशियलाइज़ेशन की अनुमति देता है। अनइनिशियलाइज़्ड `lateinit` वेरिएबल एक्सेस करने से `UninitializedPropertyAccessException` फेंका जाता है। Kotlin इनिशियलाइज़ेशन स्थिति जांचने के लिए `isInitialized` प्रॉपर्टी प्रदान करता है।
lateinit नियम (पुनर्कथन)
- केवल `var` के साथ
- Non-null टाइप्स केवल
- प्रिमिटिव टाइप्स नहीं (Int, Double, आदि)
- कस्टम गेटर/सेटर नहीं
isInitialized के साथ जांचना
class Tutorial {
lateinit var name: String
fun checkInitialization() {
// इनिशियलाइज़ेशन स्थिति प्रिंट करें
println("इनिशियलाइज़्ड पहले: ${this::name.isInitialized}") // false
// इनिशियलाइज़ करें
name = "www.tutorialspoint.com"
println("इनिशियलाइज़्ड बाद: ${this::name.isInitialized}") // true
println("मान: $name")
}
fun safeAccess() {
// सुरक्षित एक्सेस पैटर्न
if (::name.isInitialized) {
println("सुरक्षित एक्सेस: $name")
} else {
println("अभी तक इनिशियलाइज़्ड नहीं - डिफ़ॉल्ट उपयोग कर रहे हैं")
}
}
}
fun main() {
val obj = Tutorial()
obj.checkInitialization()
obj.safeAccess()
}
आउटपुट
इनिशियलाइज़्ड पहले: false इनिशियलाइज़्ड बाद: true मान: www.tutorialspoint.com सुरक्षित एक्सेस: www.tutorialspoint.com
अनइनिशियलाइज़्ड एक्सेस करने पर अपवाद
fun main() {
val obj = Tutorial()
// obj.name // यह UninitializedPropertyAccessException फेंकेगा
// obj.checkInitialization() // यह भी फेंकेगा अगर name एक्सेस किया जाता है
// सही तरीका - पहले चेक करें
if (obj::name.isInitialized) {
println(obj.name)
} else {
println("अनइनिशियलाइज़्ड - सुरक्षित रूप से संभाला गया")
}
}
उन्नत: एक्सटेंशन फंक्शन के साथ सुरक्षित एक्सेस
// किसी भी lateinit var के लिए सुरक्षित गेटर inline funKProperty1<*, T>.getOrNull(receiver: Any): T? = if (isInitialized) get(receiver) else null class Example { lateinit var data: String } fun main() { val ex = Example() // एक्सटेंशन का उपयोग println(ex::data.getOrNull(ex)) // null ex.data = "Hello" println(ex::data.getOrNull(ex)) // "Hello" // या स्टैंडर्ड लाइब्रेरी का उपयोग (Kotlin 1.6+) // println(ex::data.isInitialized) // पहले से ही दिखाया गया }
व्यावहारिक पैटर्न: लेट इनिशियलाइज़ेशन के साथ सिंगलटन
class DatabaseManager private constructor() {
lateinit var database: AppDatabase
private set
fun initialize(context: Context) {
if (!::database.isInitialized) {
database = Room.databaseBuilder(
context, AppDatabase::class.java, "app_db"
).build()
}
}
fun getDatabase(): AppDatabase {
if (!::database.isInitialized) {
throw IllegalStateException("Database not initialized. Call initialize() first.")
}
return database
}
companion object {
@Volatile private var INSTANCE: DatabaseManager? = null
fun getInstance(): DatabaseManager = INSTANCE ?: synchronized(this) {
INSTANCE ?: DatabaseManager().also { INSTANCE = it }
}
}
}
सारांश
- `::property.isInitialized` का उपयोग करके सुरक्षित रूप से जांचें
- अनइनिशियलाइज़्ड एक्सेस करने से `UninitializedPropertyAccessException` फेंका जाता है
- हमेशा एक्सेस से पहले चेक करें या try-catch का उपयोग करें
- यह रिफ्लेक्शन-आधारित है, इसलिए केवल क्लास मेंबर्स पर काम करता है (लोकल वेरिएबल्स पर नहीं)