रिफ्लेक्शन क्या है?
रिफ्लेक्शन एक ऐसा API है जो हीप क्षेत्र में लोड किए गए क्लास टाइप के ऑब्जेक्ट के माध्यम से, वांछित क्लास के इंस्टेंस को बनाने में सहायता करता है, और इंस्टेंस के फील्ड और मेथड को एक्सेस कंट्रोलर से संबंधित किए बिना उपयोग करने की अनुमति देता है।
यहां, लोड किए गए क्लास का अर्थ है कि JVM के क्लास लोडर द्वारा क्लास फ़ाइल को लोड करने के बाद, उस क्लास की जानकारी को रखने वाले क्लास टाइप का ऑब्जेक्टको बनाया जाता है और मेमोरी के हीप क्षेत्र में संग्रहीत किया जाता है। ध्यान रखें कि यह new कीवर्ड के माध्यम से बनाए गए ऑब्जेक्ट से अलग है। यदि आपको क्लास टाइप के ऑब्जेक्ट की समझ में कोई कमी है, तो java.lang.class ऑब्जेक्ट के JDK दस्तावेज़ को देखना उपयोगी होगा।
उपयोग कैसे करें
रिफ्लेक्शन का उपयोग करने से पहले, आपको हीप क्षेत्र में लोड किए गए क्लास टाइप के ऑब्जेक्ट को प्राप्त करना होगा। इसके लिए कुल तीन तरीके हैं।
- क्लास.class से प्राप्त करें
- इंस्टेंस.getClass() से प्राप्त करें
- Class.forName("क्लास का नाम") से प्राप्त करें
तीनों तरीकों से प्राप्त क्लास टाइप के इंस्टेंस समान हैं, जैसा कि आप देख सकते हैं। कोई भी विधि उपयोग करें, हैश मान समान होगा, इसलिए आपको स्थिति के अनुसार उपयुक्त विधि का उपयोग करना चाहिए।
अब, प्राप्त क्लास टाइप के माध्यम से, हम उस क्लास के इंस्टेंस को बना सकते हैं और इंस्टेंस के फील्ड और मेथड को एक्सेस कंट्रोलर से संबंधित किए बिना उपयोग कर सकते हैं। आइए पहले उस क्लास के इंस्टेंस को बनाते हैं।
getConstructor() का उपयोग करके, हम कंस्ट्रक्टर प्राप्त कर सकते हैं, और newInstance() का उपयोग करके, हम गतिशील रूप से Member इंस्टेंस बना सकते हैं।
अंत में, आइए इंस्टेंस के फील्ड और मेथड को एक्सेस कंट्रोलर से संबंधित किए बिना एक्सेस करें और उनका उपयोग करें।
getDeclaredFileds() का उपयोग करके, हम क्लास के सभी इंस्टेंस वेरिएबल प्राप्त कर सकते हैं, get() का उपयोग करके, हम फील्ड मान प्राप्त कर सकते हैं, और set() का उपयोग करके, हम फील्ड मान को संशोधित कर सकते हैं। यहाँ ध्यान देने योग्य बात यह है कि जब private एक्सेस कंट्रोलर वाले फील्ड को एक्सेस करते हैं, तो हमें setAccessible() के आर्ग्यूमेंट को true में बदलना होगा।
इसी तरह, getDeclaredMethod() का उपयोग करके मेथड प्राप्त किया जा सकता है। इस समय, मेथड का नाम और पैरामीटर टाइप को आर्ग्यूमेंट के रूप में पास करना होगा। उसी तरह, जब private एक्सेस कंट्रोलर वाले मेथड को एक्सेस करते हैं, तो हमें setAccessible() के आर्ग्यूमेंट को true में बदलना होगा। अंत में, invoke() मेथड का उपयोग करके, हम रिफ्लेक्शन API द्वारा प्राप्त मेथड को कॉल कर सकते हैं।
लाभ और हानि
- लाभ
- रनटाइम पर, क्लास के इंस्टेंस बनाए जा सकते हैं, और एक्सेस कंट्रोलर से संबंधित किए बिना फील्ड और मेथड को एक्सेस किया जा सकता है, जिससे लचीलापन मिलता है ताकि आवश्यक कार्यों को किया जा सके।
- हानि
- इंकेप्सुलेशन को कम करता है।
- रनटाइम पर इंस्टेंस बनाए जाते हैं, इसलिए कंपाइल टाइम पर टाइप की जांच नहीं की जा सकती है।
- रनटाइम पर इंस्टेंस बनाए जाते हैं, इसलिए विशिष्ट ऑपरेशन प्रवाह को समझना मुश्किल होता है।
- केवल फील्ड और मेथड को एक्सेस करने की तुलना में, रिफ्लेक्शन का उपयोग करके एक्सेस करने पर प्रदर्शन धीमा होता है (सभी परिस्थितियों में प्रदर्शन धीमा नहीं होता है)।
इस्तेमाल करने के कारण
रिफ्लेक्शन API के माध्यम से, हम रनटाइम के दौरान क्लास जानकारी तक पहुंच सकते हैं और क्लास को अपनी इच्छानुसार हेरफेर कर सकते हैं। यहां तक कि private एक्सेस कंट्रोलर वाले फील्ड और मेथड को भी संशोधित किया जा सकता है। चूंकि ऑब्जेक्ट-ओरिएंटेड डिज़ाइन में इंकेप्सुलेशन महत्वपूर्ण है, इसलिए ऐसा प्रतीत होता है कि इसका उपयोग नहीं किया जाना चाहिए।
छोटे पैमाने के कंसोल स्तर पर, डेवलपर कंपाइल टाइम पर प्रोग्राम में उपयोग किए जाने वाले ऑब्जेक्ट और निर्भरता संबंधों को पूरी तरह से समझ सकता है। हालांकि, फ्रेमवर्क जैसे बड़े पैमाने के विकास चरण में, कई ऑब्जेक्ट और निर्भरता संबंधों को समझना मुश्किल होता है। इस समय, रिफ्लेक्शन का उपयोग करके, हम गतिशील रूप से क्लास बना सकते हैं और निर्भरता संबंध स्थापित कर सकते हैं।
उदाहरण के लिए, Spring के Bean Factory को देखें, यदि आप केवल @Controller, @Service, @Repository जैसे एनोटेशन लगाते हैं, तो Bean Factory स्वचालित रूप से उस एनोटेशन वाले क्लास को बनाएगा और उसे प्रबंधित करेगा। डेवलपर ने Bean Factory को क्लास के बारे में सूचित नहीं किया है, लेकिन यह रिफ्लेक्शन के कारण संभव है। रनटाइम पर, यह एनोटेशन वाले क्लास को खोजेगा और यदि वह पाया जाता है, तो रिफ्लेक्शन का उपयोग करके, उस क्लास के इंस्टेंस को बनाएगा, आवश्यक फील्ड इंजेक्ट करेगा और Bean Factory में संग्रहीत करेगा।
बेशक, जैसा कि ऊपर उल्लेख किया गया है, यह इंकेप्सुलेशन को कम करता है, इसलिए इसे केवल आवश्यक होने पर ही उपयोग करना चाहिए।
टिप्पणियाँ0