2010-03-21 15 views
8

मैं सिर्फ उत्सुक था, हमें पहले स्थान पर reflection का उपयोग क्यों करना चाहिए?जावा/सी # आदि 0 में प्रतिबिंब का उपयोग क्या है

// Without reflection 
Foo foo = new Foo(); 
foo.hello(); 

// With reflection 
Class cls = Class.forName("Foo"); 
Object foo = cls.newInstance(); 
Method method = cls.getMethod("hello", null); 
method.invoke(foo, null); 

हम केवल एक वस्तु बना सकते हैं और वर्ग की विधि कॉल कर सकते हैं, लेकिन क्यों एक ही का उपयोग कर forName, newInstance और getMthod कार्यों करते हैं?

सबकुछ गतिशील बनाने के लिए?

उत्तर

27

बस शब्दों में कहें: क्योंकि कभी-कभी आप संकलित समय पर "फू" या "हैलो" भागों को नहीं जानते हैं।

उस समय का विशाल बहुमत जब आप करते हैं तो यह पता है, इसलिए प्रतिबिंब का उपयोग करने के लायक नहीं है। कभी-कभी, हालांकि, आप नहीं करते - और उस समय, प्रतिबिंब वह है जिसे आप बदल सकते हैं।

उदाहरण के तौर पर, protocol buffers आपको कोड उत्पन्न करने की अनुमति देता है जिसमें या तो संदेश पढ़ने और लिखने के लिए पूर्ण स्थैतिक-टाइप कोड शामिल है, या यह केवल इतना उत्पन्न करता है कि शेष प्रतिबिंब द्वारा किया जा सकता है: प्रतिबिंब मामले में, भार/कोड को प्रतिबिंब के माध्यम से गुणों को प्राप्त करना और सेट करना है - यह संदेश वर्णनकर्ता के कारण शामिल गुणों के नामों को जानता है। यह बहुत अधिक (बहुत) धीमा है लेकिन परिणामस्वरूप काफी कम कोड उत्पन्न होता है।

एक और उदाहरण निर्भरता इंजेक्शन होगा, जहां निर्भरताओं के लिए उपयोग किए जाने वाले प्रकारों के नाम अक्सर कॉन्फ़िगरेशन फ़ाइलों में प्रदान किए जाते हैं: DI ढांचे को तब शामिल सभी घटकों का निर्माण करने के लिए प्रतिबिंब का उपयोग करना होगा, साथ ही रचनाकारों और/या गुणों को ढूंढना होगा रास्ता।

+0

यह क्यों कम किया गया था? – SLaks

+0

+1, जैसा कि ऐसा है। –

+0

@ जोन: क्या यह एक डुप्लिकेट नहीं है? –

3

एक सामान्य उपयोग एक प्लग-इन तंत्र है, जो कक्षाओं (आमतौर पर इंटरफेस के कार्यान्वयन) का समर्थन करता है जो संकलन समय पर अज्ञात हैं।

0

जोन्स के जवाब के अलावा, एक और उपयोग "पानी में अपने पैर की अंगुली डुबकी" करने में सक्षम होना है ताकि परीक्षण किया जा सके कि JVM में दी गई सुविधा मौजूद है या नहीं।

ओएस एक्स के तहत एक जावा एप्लिकेशन अच्छा दिखता है अगर कुछ ऐप्पल-प्रदत्त वर्गों को बुलाया जाता है। परीक्षण करने का सबसे आसान तरीका यह है कि क्या ये कक्षाएं मौजूद हैं, प्रतिबिंब के साथ परीक्षण करना है

1

यह क्रमबद्धता और ऑब्जेक्ट-रिलेशनल मैपिंग जैसी चीजों के लिए उपयोगी है। ऑब्जेक्ट की सभी संपत्तियों को प्राप्त करने के लिए प्रतिबिंब का उपयोग कर किसी ऑब्जेक्ट को क्रमबद्ध करने के लिए आप एक सामान्य फ़ंक्शन लिख सकते हैं। सी ++ में, आपको प्रत्येक वर्ग के लिए एक अलग कार्य लिखना होगा।

3

आप किसी भी प्रक्रिया को स्वचालित करने के लिए प्रतिबिंब का उपयोग कर सकते हैं जो उपयोगी रूप से ऑब्जेक्ट के तरीकों और/या गुणों की सूची का उपयोग कर सकता है। यदि आपने कभी भी समय लिखने का कोड बिताया है जो किसी ऑब्जेक्ट के फ़ील्ड में मोटे तौर पर एक ही चीज़ करता है - डेटा को सहेजने और लोड करने का स्पष्ट तरीका अक्सर इस तरह काम करता है - तो यह आपके लिए कुछ प्रतिबिंब स्वचालित रूप से कर सकता है।

सबसे आम अनुप्रयोगों शायद इन तीन हैं:

  • क्रमबद्धता (देखें, जैसे, नेट के XmlSerializer) संपादन वस्तुओं 'गुण (जैसे, Xcode के इंटरफ़ेस बिल्डर, नेट के संवाद के लिए विजेट का
  • पीढ़ी डिजाइनर)
  • कारखाने जो रचनाकारों के लिए कक्षाओं की जांच करके और निर्माण पर उपयुक्त वस्तुओं की आपूर्ति करके मनमानी निर्भरताओं के साथ वस्तुओं को बनाते हैं (उदाहरण के लिए, किसी भी निर्भरता इंजेक्शन ढांचे)
2

प्रतिबिंब का उपयोग करके, आप आसानी से कॉन्फ़िगरेशन लिख सकते हैं कि पाठ में विस्तार विधियों/फ़ील्ड, और इनका उपयोग करके ढांचा क्षेत्र का एक टेक्स्ट विवरण पढ़ सकता है और वास्तविक संबंधित फ़ील्ड ढूंढ सकता है।

उदा। JXPath आप इस तरह की वस्तुओं नेविगेट करने के लिए अनुमति देता है:

//company[@name='Sun']/address 

तो JXPath एक विधि getCompany() (company से सम्बंधित) के लिए दिखाई देगा, कि एक क्षेत्र कहा जाता name आदि

आप की बहुत सारी में इस मिल जाएगा जावा में ढांचे जैसे उदाहरण जावाबीन्स, स्प्रिंग इत्यादि

4

जब भी आप (= आपकी विधि/आपकी कक्षा) संकलित समय पर नहीं जानते हैं तो प्रकार तत्काल होना चाहिए या जिस विधि को इसे लागू करना चाहिए।

इसके अलावा, कई ढांचे आपके ऑब्जेक्ट्स का विश्लेषण और उपयोग करने के लिए प्रतिबिंब का उपयोग करते हैं। उदाहरण के लिए:

  • हाइबरनेट/nhibernate (और किसी भी वस्तु-संबंधपरक नक्शाकार) अपनी कक्षाओं के सभी गुण का निरीक्षण करने के प्रतिबिंब का उपयोग इतना है कि यह उन्हें अपडेट करने या जब डेटाबेस कार्यों को क्रियान्वित करने के लिए उन्हें का उपयोग करने में सक्षम है
  • आप कर सकते हैं इसे कॉन्फ़िगर करने योग्य बनाना चाहते हैं कि उपयोगकर्ता द्वारा परिभाषित वर्ग की विधि डिफ़ॉल्ट रूप से आपके एप्लिकेशन द्वारा निष्पादित की जाती है। कॉन्फ़िगर किया गया मान String है, और आप लक्ष्य वर्ग प्राप्त कर सकते हैं, उस विधि को प्राप्त करें जिसमें कॉन्फ़िगर किया गया नाम है, और संकलन समय पर इसे जानने के बिना इसे आमंत्रित करें।
  • एनोटेशन को पार्स प्रतिबिंब द्वारा किया जाता है
1

मैं कुछ सत्यापन कक्षाओं में यह प्रयोग किया जाता है इससे पहले कि, जहां मैं निर्माता में एक बड़े, जटिल डेटा संरचना से पारित कर दिया और फिर एक असंख्य (कुछ सौ वास्तव में) की जाँच करने के तरीकों भाग गया डेटा की वैधता। मेरी सभी सत्यापन विधियां निजी थीं और बुलियन लौट आईं, इसलिए मैंने एक "मान्य" विधि बनाई जिसे आप कॉल कर सकते थे, जो कि बूलियन लौटने से कक्षा में सभी निजी तरीकों का आह्वान करने के लिए प्रतिबिंबित होता था।

इसने वैध विधि को अधिक संक्षिप्त (प्रत्येक छोटी विधि को गिनने की आवश्यकता नहीं थी) और गलती से सभी विधियों को चलाया गया था (उदाहरण के लिए कोई नया सत्यापन नियम लिखता है और इसे मुख्य विधि में कॉल करना भूल जाता है)।

प्रतिबिंब का उपयोग करने के बाद बदलने के बाद मुझे प्रदर्शन में कोई सार्थक नुकसान नहीं हुआ, और कोड को बनाए रखना आसान था।

0

कुछ बार आपको फ्लाई या किसी अन्य जगह से कक्षा का ऑब्जेक्ट बनाने की आवश्यकता नहीं है, जावा कोड (उदा। जेएसपी) नहीं। उस समय प्रतिबिंब उपयोगी है।

संबंधित मुद्दे