Java प्रोग्रामर Kotlin पर स्विच करते समय क्यों रोते हैं?
\n\nकल्पना करें: आप Java में कोड लिख रहे हैं, एक फ़ाइल खोलते हैं, डेटा पढ़ते हैं, और फिर... उसे बंद करना भूल जाते हैं। यह दर्द आप जानते हैं ना? Java में इसके लिए try-with-resources कंस्ट्रक्शन बनाया गया, जो अपने आप close() को कॉल करता है। लेकिन जब डेवलपर्स Kotlin पर आते हैं, तो वे अक्सर असमंजस में पड़ जाते हैं: "मेरा पसंदीदा try (Resource res = ...) कहाँ गया?"
स्पॉयलर: Kotlin में try-with-resources एक अलग भाषा कंस्ट्रक्शन के रूप में मौजूद नहीं है। और यह अच्छी खबर है। इसके बजाय, भाषा एक अधिक सुंदर और संक्षिप्त समाधान प्रदान करती है — use फ़ंक्शन। आइए समझते हैं कि यह कैसे काम करता है और क्यों आपका कोड साफ़ हो जाएगा।
समस्या: संसाधनों को बंद करना ज़रूरी है
\n\nकोई भी बाहरी संसाधन — फ़ाइल, नेटवर्क कनेक्शन, डेटाबेस — को मैन्युअल प्रबंधन की आवश्यकता होती है। यदि आप FileInputStream खोलते हैं और इसे बंद नहीं करते हैं, तो सिस्टम "लीक" हो सकता है (मेमोरी लीक), और फ़ाइल अन्य प्रक्रियाओं के लिए लॉक रह सकती है।
Java में इस समस्या को दो तरीकों से हल किया जाता है:
\n\n- \n
- पुराना तरीका:
finallyब्लॉक के साथ स्पष्ट रूप सेclose()कॉल करना। \n - नया तरीका:
try-with-resources(Java 7 में आया)। \n
Kotlin ने एक कदम आगे बढ़कर एक्सटेंशन फ़ंक्शन और लैम्ब्डा का उपयोग किया है, ताकि कोड न केवल सुरक्षित हो, बल्कि सुंदर भी हो।
\n\nJava में try-with-resources कैसा दिखता है?
\n\nतुलना के लिए, आइए क्लासिक Java कोड देखें:
\n\ntry (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {\n String line = br.readLine();\n System.out.println(line);\n} catch (IOException e) {\n e.printStackTrace();\n}\n// br अपने आप बंद हो जाता है\n\n\nसब ठीक है, लेकिन कुछ बारीकियाँ हैं:
\n- \n
- वेरिएबल को
tryके कोष्ठक के अंदर घोषित करना होता है। \n - केवल वे क्लासेज़ समर्थित हैं जो
AutoCloseableको इम्प्लीमेंट करती हैं। \n - यदि कई संसाधन हों, तो कोड बोझिल हो जाता है। \n
Kotlin का तरीका: use फ़ंक्शन
\n\nKotlin में संसाधनों के साथ सुरक्षित रूप से काम करने के लिए use फ़ंक्शन का उपयोग किया जाता है। यह Closeable (और Java संगतता के लिए AutoCloseable) इंटरफ़ेस के लिए एक एक्सटेंशन के रूप में परिभाषित है।
यहाँ Kotlin में वही उदाहरण है:
\n\nimport java.io.BufferedReader\nimport java.io.FileReader\n\nfun main() {\n BufferedReader(FileReader("file.txt")).use { reader ->\n val line = reader.readLine()\n println(line)\n }\n // reader अपने आप बंद हो जाता है\n}\n\n\nसाफ़, संक्षिप्त, बिना किसी अतिरिक्त try-catch के? बिल्कुल नहीं। use अपने आप एक्सेप्शन नहीं पकड़ता। यह केवल ब्लॉक के अंत में close() कॉल करने की गारंटी देता है। यदि त्रुटि को संभालना है, तो बाहर try-catch जोड़ें:
try {\n BufferedReader(FileReader("file.txt")).use { reader ->\n val line = reader.readLine()\n println(line)\n }\n} catch (e: IOException) {\n println("फ़ाइल पढ़ने में त्रुटि: ${e.message}")\n}\n\n\nuse अंदर से कैसे काम करता है?
\n\nजादू को समझने के लिए, Kotlin के सोर्स कोड में झाँकते हैं। use फ़ंक्शन स्टैंडर्ड लाइब्रेरी में लगभग इस प्रकार परिभाषित है:
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {\n var exception: Throwable? = null\n try {\n return block(this)\n } catch (e: Throwable) {\n exception = e\n throw e\n } finally {\n when {\n exception == null -> close()\n else -> try {\n close()\n } catch (closeException: Throwable) {\n // एक्सेप्शन को दबाएं, इसे मुख्य एक्सेप्शन में जोड़ें\n exception.addSuppressed(closeException)\n }\n }\n }\n}\n