Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

Kotlin - प्रॉपर्टी इनिशियलाइज़ेशन: by lazy बनाम lateinit

परिचय

Kotlin दो तंत्र प्रदान करता है जब प्रॉपर्टी को तुरंत इनिशियलाइज़ नहीं किया जा सकता: lateinit (var के लिए) और by lazy (val के लिए)। दोनों डिफर्ड इनिशियलाइज़ेशन सक्षम करते हैं लेकिन अलग-अलग उपयोग के मामले हैं।

lateinit (लेट इनिशियलाइज़ेशन)

नियम:

  • केवल var के साथ (परिवर्तनीय)
  • केवल non-null टाइप्स के साथ
  • प्रिमिटिव टाइप्स के साथ काम नहीं करता (Int, Boolean, आदि)
  • कस्टम गेटर/सेटर नहीं हो सकते
  • चेक करने के लिए `::property.isInitialized` का उपयोग करें

उदाहरण:

class Tutorial {
    lateinit var name: String
    
    fun checkLateInit() {
        // इनिशियलाइज़ेशन चेक करें
        if (::name.isInitialized) {
            println("नाम पहले से इनिशियलाइज़्ड: $name")
        } else {
            println("नाम अभी तक इनिशियलाइज़्ड नहीं")
            name = "www.tutorialspoint.com"
            println("अब इनिशियलाइज़्ड: $name")
        }
    }
    
    fun reset() {
        // lateinit को रीसेट नहीं किया जा सकता, केवल पुनः असाइन
        name = "नया मान"
    }
}

fun main() {
    val obj = Tutorial()
    obj.checkLateInit()  // पहले इनिशियलाइज़ करता है
    obj.checkLateInit()  // पहले से इनिशियलाइज़्ड दिखाता है
}

आउटपुट

नाम अभी तक इनिशियलाइज़्ड नहीं
अब इनिशियलाइज़्ड: www.tutorialspoint.com
नाम पहले से इनिशियलाइज़्ड: www.tutorialspoint.com

by lazy (लेज़ी इनिशियलाइज़ेशन)

नियम:

  • केवल val के साथ (अपरिवर्तनीय रेफरेंस)
  • थ्रेड-सेफ डिफ़ॉल्ट रूप से (`LazyThreadSafetyMode.SYNCHRONIZED`)
  • केवल पहली एक्सेस पर इनिशियलाइज़ होता है
  • बाद के एक्सेस के लिए मान कैश करता है
  • पुनः असाइन नहीं किया जा सकता

उदाहरण:

class Demo {
    val myName: String by lazy {
        println("लेज़ी इनिशियलाइज़ेशन हो रहा है...")
        "www.tutorialspoint.com"
    }
    
    // अलग थ्रेड-सेफ्टी मोड
    val threadLocal: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
        "प्रकाशन मोड"
    }
    
    val noSync: String by lazy(LazyThreadSafetyMode.NONE) {
        "कोई सिंक नहीं"
    }
}

fun main() {
    val obj = Demo()
    println("पहली कॉल: ${obj.myName}")
    println("दूसरी कॉल: ${obj.myName}")  // कैश्ड मान
    println("तीसरी कॉल: ${obj.myName}")  // कैश्ड मान
}

आउटपुट

लेज़ी इनिशियलाइज़ेशन हो रहा है...
पहली कॉल: www.tutorialspoint.com
दूसरी कॉल: www.tutorialspoint.com
तीसरी कॉल: www.tutorialspoint.com

तुलना तालिका

पहलूlateinit varby lazy val
परिवर्तनीयतापरिवर्तनीय (var)अपरिवर्तनीय रेफरेंस (val)
इनिशियलाइज़ेशन ट्रिगरमैन्युअल असाइनमेंटपहली एक्सेस पर स्वचालित
पुनः असाइनमेंटअनुमतअनुमत नहीं
थ्रेड-सेफ्टीनहीं (मैन्युअल सिंक आवश्यक)हाँ (डिफ़ॉल्ट SYNCHRONIZED)
नल अनुमतनहींनहीं (लेकिन nullable val के साथ उपयोग कर सकते हैं)
प्रिमिटिव टाइप्सनहींनहीं (लेकिन wrapper types के साथ)
इनिशियलाइज़ेशन चेक`::prop.isInitialized`N/A (हमेशा एक्सेस पर इनिशियलाइज़्ड)
उपयोग का मामलाडिपेंडेंसी इंजेक्शन, व्यू बाइंडिंगमहंगी गणना, सिंगलटन

व्यावहारिक उदाहरण

lateinit उपयोग मामला: व्यू बाइंडिंग / डिपेंडेंसी इंजेक्शन

class MainActivity : AppCompatActivity() {
    // onCreate में इनिशियलाइज़ होगा
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: MainViewModel
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)  // यहां इनिशियलाइज़
        viewModel = ViewModelProvider(this)[MainViewModel::class.java]
        setContentView(binding.root)
    }
}

by lazy उपयोग मामला: महंगी गणना / सिंगलटन

class Repository {
    // डेटाबेस कनेक्शन - केवल जब पहली बार जरूरत हो
    val database: AppDatabase by lazy {
        Room.databaseBuilder(context, AppDatabase::class.java, "db").build()
    }
    
    // रेट्रोफिट इंस्टेंस
    val apiService: ApiService by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .build()
            .create(ApiService::class.java)
    }
}

सारांश

  • lateinit var - जब आप बाद में मैन्युअल रूप से इनिशियलाइज़ करेंगे (DI, व्यू बाइंडिंग, टेस्ट सेटअप)
  • by lazy val - जब मान महंगा हो और पहली एक्सेस पर ऑन-डिमांड गणना करना चाहते हैं
  • दोनों non-null टाइप्स के लिए हैं
  • प्रिमिटिव टाइप्स के लिए nullable wrapper या `LateInit`/`Lazy` डेलीगेट्स का उपयोग करें
  1. - एंड्रॉइड में Kotlin का उपयोग करके GridView स्क्रॉलिंग को कैसे अक्षम करें?

    परिचय यह उदाहरण दर्शाता है कि एंड्रॉइड में Kotlin का उपयोग करके GridView की स्क्रॉलिंग कार्यक्षमता को कैसे अक्षम किया जाए। यह तब उपयोगी होता है जब आप ग्रिड आइटम को स्थिर रखना चाहते हैं और उपयोगकर्ता को स्क्रॉल करने से रोकना चाहते हैं। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में जाएं, File → New P

  1. - CSS z-index प्रॉपर्टी का उपयोग

    z-index प्रॉपर्टी का उपयोग position प्रॉपर्टी के साथ लेयर्स का प्रभाव बनाने के लिए किया जाता है। आप निर्दिष्ट कर सकते हैं कि कौन सा एलिमेंट शीर्ष पर आना चाहिए और कौन सा नीचे। उदाहरण z-index प्रॉपर्टी को लागू करने के लिए निम्न कोड चलाएं: <html> <head> </head> <body>

  1. CSS में Display प्रॉपर्टी का उपयोग CSS में Display प्रॉपर्टी का उपयोग

    सभी HTML एलिमेंट्स की CSS Display प्रॉपर्टी के लिए एक डिफॉल्ट मान सेट होता है। यह प्रॉपर्टी निर्दिष्ट करती है कि एलिमेंट डॉक्यूमेंट में कैसे रेंडर होगा। नोट: डिफॉल्ट display प्रॉपर्टी को ओवरराइड किया जा सकता है लेकिन इससे एलिमेंट का टाइप नहीं बदलता, केवल डॉक्यूमेंट पर उसका डिस्प्ले व्यवहार बदलता है