प्रतिबिंब क्या है और यह क्यों उपयोगी है?


2123

प्रतिबिंब क्या है, और यह क्यों उपयोगी है?

मुझे जावा में विशेष रूप से दिलचस्पी है, लेकिन मुझे लगता है कि सिद्धांत किसी भी भाषा में समान हैं।


9
मेरे लिए यह रनटाइम पर क्लास के नाम लेने और उस क्लास के ऑब्जेक्ट बनाने का एक तरीका है।
नाबिन

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


4
@ बिलके की टिप्पणी के अलावा: प्रतिबिंब बहुत शक्तिशाली है, मैं इसे जादू कहूंगा। महान शक्ति के साथ महान जिम्मेदारी आती है। इसका उपयोग केवल तभी करें जब आपको पता हो कि आप क्या कर रहे हैं।
एम सी सम्राट

आप मैनिफोल्ड का उपयोग करके प्रतिबिंब से जुड़े कई नुकसानों से बच सकते हैं @Jailbreak। यह निजी क्षेत्रों, विधियों, आदि के लिए प्रत्यक्ष -प्रकार-सुरक्षित पहुंच प्रदान करता है, जावा कंपाइलर को सुरक्षित रूप से अपने कोड को सत्यापित करने दें और कई गुना आपके लिए अंतर्निहित प्रतिबिंब पहुंच उत्पन्न करने दें। और जानें: कई गुना।
Scott

जवाबों:


1716

नाम प्रतिबिंब का उपयोग कोड का वर्णन करने के लिए किया जाता है जो एक ही सिस्टम (या स्वयं) में अन्य कोड का निरीक्षण करने में सक्षम है।

उदाहरण के लिए, मान लें कि आपके पास जावा में अज्ञात प्रकार की कोई वस्तु है, और यदि आप मौजूद हैं, तो आप उस पर 'doSomething' विधि को कॉल करना चाहेंगे। जावा का स्टैटिक टाइपिंग सिस्टम वास्तव में इसका समर्थन करने के लिए डिज़ाइन नहीं किया गया है जब तक कि वस्तु एक ज्ञात इंटरफ़ेस के अनुरूप न हो, लेकिन प्रतिबिंब का उपयोग करते हुए, आपका कोड ऑब्जेक्ट को देख सकता है और यह पता लगा सकता है कि क्या यह 'doSomething' नामक एक विधि है और फिर इसे कॉल करें यदि आप चाहना।

तो, आपको जावा में इसका एक कोड उदाहरण देने के लिए (कल्पना करें कि प्रश्न में वस्तु foo है):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

जावा में एक बहुत ही सामान्य उपयोग मामला एनोटेशन के साथ उपयोग है। JUnit 4, उदाहरण के लिए, @Test एनोटेशन के साथ टैग की गई विधियों के लिए अपनी कक्षाओं के माध्यम से देखने के लिए प्रतिबिंब का उपयोग करेगा, और फिर यूनिट परीक्षण चलाते समय उन्हें कॉल करेगा।

Http://docs.oracle.com/javase/tutorial/reflect/index.html पर आरंभ करने के लिए कुछ अच्छे प्रतिबिंब उदाहरण हैं

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

टिप्पणी से अपडेट करें:

सिस्टम में कोड का निरीक्षण करने और ऑब्जेक्ट प्रकार देखने की क्षमता प्रतिबिंब नहीं है, बल्कि टाइप इंट्रोस्पेक्शन है। परावर्तन फिर आत्मनिरीक्षण का उपयोग करके रनटाइम में संशोधन करने की क्षमता है। यहाँ अंतर आवश्यक है क्योंकि कुछ भाषाएं आत्मनिरीक्षण का समर्थन करती हैं, लेकिन प्रतिबिंब का समर्थन नहीं करती हैं। ऐसा ही एक उदाहरण है C ++


32
u u कृपया समझा सकते हैं कि इस पंक्ति में उस अशक्त पैरामीटर का क्या महत्व है विधि विधि = foo.getClass ()। getMethod ("doSomething", null);
कृष्ण चैतन्य

54
नल इंगित करता है कि कोई विधि नहीं है foo विधि को पारित किया जा रहा है। देखें docs.oracle.com/javase/6/docs/api/java/lang/reflect/... , java.lang.Object ... जानकारी के लिए)।
मैट शेपर्ड

791
बस इसे साफ करने के लिए क्योंकि इसमें बहुत सारे उतार-चढ़ाव हैं। सिस्टम में कोड का निरीक्षण करने और ऑब्जेक्ट प्रकार देखने की क्षमता प्रतिबिंब नहीं है, बल्कि टाइप इंट्रोस्पेक्शन है। परावर्तन तो आत्मनिरीक्षण का उपयोग करके रनटाइम में संशोधन करने की क्षमता है। यहाँ अंतर आवश्यक है क्योंकि कुछ भाषाएं आत्मनिरीक्षण का समर्थन करती हैं, लेकिन प्रतिबिंब का समर्थन नहीं करती हैं। ऐसा ही एक उदाहरण है C ++।
Bigtunacan

39
मुझे प्रतिबिंब पसंद है लेकिन अगर आपका कोड पर नियंत्रण है तो इस उत्तर में निर्दिष्ट प्रतिबिंब का उपयोग करना एकतरफा है और इसलिए एक दुरुपयोग है - आपको टाइप इंट्रस्पेक्शन (उदाहरण) और मजबूत प्रकारों का उपयोग करना चाहिए। अगर कोई रास्ता है लेकिन कुछ करने के लिए प्रतिबिंब है, तो यह है कि यह कैसे किया जाना चाहिए। प्रतिबिंब गंभीर दिल का दर्द का कारण बनता है क्योंकि आप एक सांख्यिकीय रूप से टाइप की गई भाषा का उपयोग करने के सभी फायदे खो देते हैं। यदि आपको इसकी आवश्यकता है तो आपको इसकी आवश्यकता है, हालांकि तब भी मैं स्प्रिंग जैसे एक पूर्व-पैक समाधान पर विचार करूंगा या ऐसा कुछ जो पूरी तरह से प्रतिबिंब को आवश्यक रूप से संलग्न कर देगा - IE: किसी और को सिरदर्द होने दें।
बिल के

6
@bigtunacan आपको वह जानकारी कहां से मिली? मैं Oracle से आधिकारिक जावा प्रलेखन में प्रयुक्त "प्रतिबिंब" शब्द देखता हूं, जो न केवल रनटाइम में परिवर्तन करने की क्षमता का वर्णन करता है, बल्कि किसी वस्तु के प्रकार को देखने की क्षमता भी है। ऐसा नहीं है कि अधिकांश तथाकथित "प्रकार आत्मनिरीक्षण" संबंधित वर्गों का उल्लेख (पूर्व: Method, Constructor, Modifier, Field, Member, मूल रूप से जाहिरा तौर पर सभी सिवाय Class) के भीतर हैं java.lang.*reflect*पैकेज। शायद अवधारणा "प्रतिबिंब" में व्यापक रूप से "टाइप आत्मनिरीक्षण" और रन-टाइम में संशोधन दोनों शामिल हैं?
रेस्टइनपीस

246

परावर्तन एक भाषा की क्षमता और रनटाइम पर कक्षाओं, विधियों, विशेषताओं आदि का निरीक्षण करने की क्षमता है।

उदाहरण के लिए, जावा की सभी वस्तुओं में वह विधि है getClass(), जो आपको वस्तु के वर्ग का निर्धारण करने देती है, भले ही आप इसे संकलन समय पर न जानते हों (जैसे कि आपने इसे घोषित किया है Object) - यह तुच्छ लग सकता है, लेकिन ऐसा प्रतिबिंब संभव नहीं है जैसे कम गतिशील भाषाओं में C++। अधिक उन्नत उपयोग आपको सूची और कॉल करने के तरीके, निर्माता आदि की सुविधा देता है।

प्रतिबिंब महत्वपूर्ण है क्योंकि यह आपको ऐसे प्रोग्राम लिखने देता है, जिन्हें संकलन के समय सब कुछ "पता" करने की आवश्यकता नहीं होती है, जिससे वे अधिक गतिशील हो जाते हैं, क्योंकि वे रनटाइम पर एक साथ बंधे हो सकते हैं। कोड ज्ञात इंटरफेस के खिलाफ लिखा जा सकता है, लेकिन उपयोग किए जाने वाले वास्तविक वर्गों को कॉन्फ़िगरेशन फ़ाइलों से प्रतिबिंब का उपयोग करके तत्काल किया जा सकता है।

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


2
तो दूसरे शब्दों में, आप इसे योग्य नाम से एक उदाहरण बना सकते हैं और संकलक इसके बारे में शिकायत नहीं करेंगे (क्योंकि कहते हैं कि आप वर्ग नाम के लिए सिर्फ एक स्ट्रिंग का उपयोग करते हैं)। फिर, रन टाइम पर, अगर वह क्लास मौजूद नहीं है तो आपको अपवाद मिलेगा। आपने इस मामले में संकलक को दरकिनार कर दिया। क्या आप मुझे इसके लिए कुछ विशिष्ट उपयोग का मामला देंगे? मैं सिर्फ तस्वीर नहीं कर सकता जब मैं इसे चुनूंगा।
फर्नांडो गेब्रियल 21

3
@FernandoGabrieli जबकि यह सच है कि प्रतिबिंब के साथ रनटाइम त्रुटियों को बनाना आसान है, रनटाइम अपवादों को जोखिम में डाले बिना प्रतिबिंब का उपयोग करना भी पूरी तरह से संभव है। जैसा कि मेरे जवाब में संकेत दिया गया है, प्रतिबिंब का एक सामान्य उपयोग पुस्तकालयों या रूपरेखाओं के लिए है, जो स्पष्ट रूप से संकलन समय पर आवेदन की संरचना को नहीं जान सकते हैं , क्योंकि वे आवेदन से अलग संकलित हैं। कोई भी पुस्तकालय जो "कन्वेंशन द्वारा कोड" का उपयोग करता है, प्रतिबिंब का उपयोग करने की संभावना है, लेकिन जरूरी नहीं कि जादू के तार का उपयोग कर।
लीडमैन

C++रन-टाइम प्रकार की जानकारी है। RTTI
Ayxan

114

प्रतिबिंब के मेरे पसंदीदा उपयोगों में से एक जावा डंप विधि के नीचे है। यह किसी भी वस्तु को एक पैरामीटर के रूप में लेता है और हर क्षेत्र के नाम और मूल्य को प्रिंट करने के लिए जावा प्रतिबिंब एपीआई का उपयोग करता है।

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public static String dump(Object o, int callCount) {
    callCount++;
    StringBuffer tabs = new StringBuffer();
    for (int k = 0; k < callCount; k++) {
        tabs.append("\t");
    }
    StringBuffer buffer = new StringBuffer();
    Class oClass = o.getClass();
    if (oClass.isArray()) {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("[");
        for (int i = 0; i < Array.getLength(o); i++) {
            if (i < 0)
                buffer.append(",");
            Object value = Array.get(o, i);
            if (value.getClass().isPrimitive() ||
                    value.getClass() == java.lang.Long.class ||
                    value.getClass() == java.lang.String.class ||
                    value.getClass() == java.lang.Integer.class ||
                    value.getClass() == java.lang.Boolean.class
                    ) {
                buffer.append(value);
            } else {
                buffer.append(dump(value, callCount));
            }
        }
        buffer.append(tabs.toString());
        buffer.append("]\n");
    } else {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("{\n");
        while (oClass != null) {
            Field[] fields = oClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                buffer.append(tabs.toString());
                fields[i].setAccessible(true);
                buffer.append(fields[i].getName());
                buffer.append("=");
                try {
                    Object value = fields[i].get(o);
                    if (value != null) {
                        if (value.getClass().isPrimitive() ||
                                value.getClass() == java.lang.Long.class ||
                                value.getClass() == java.lang.String.class ||
                                value.getClass() == java.lang.Integer.class ||
                                value.getClass() == java.lang.Boolean.class
                                ) {
                            buffer.append(value);
                        } else {
                            buffer.append(dump(value, callCount));
                        }
                    }
                } catch (IllegalAccessException e) {
                    buffer.append(e.getMessage());
                }
                buffer.append("\n");
            }
            oClass = oClass.getSuperclass();
        }
        buffer.append(tabs.toString());
        buffer.append("}\n");
    }
    return buffer.toString();
}

8
Callcount को किस पर सेट किया जाना चाहिए?
टॉम

8
जब मैंने इसे चलाया तो मुझे "AWT-EventQueue-0" java.lang.StackOverflowError थ्रेड में एक अपवाद मिला।
टॉम

3
@ टोम callCountको शून्य पर सेट किया जाना चाहिए। यह निर्धारित करने के लिए मूल्य का उपयोग किया जाता है कि आउटपुट की प्रत्येक पंक्ति में कितने टैब होने चाहिए: हर बार डंप करने के लिए "सबजेक्ट" को डंप करने की आवश्यकता होती है, आउटपुट माता-पिता में नेस्टेड के रूप में प्रिंट होता है। दूसरे में लपेटे जाने पर यह विधि उपयोगी साबित होती है। विचार करें printDump(Object obj){ System.out.println(dump(obj, 0)); }
6

1
Java.lang.StackOverflowError अनियंत्रित प्रत्यावर्तन की वजह से, वृत्तीय संदर्भ के मामले में बनाया जा सकता है: buffer.append (डंप (मूल्य, callCount))
अरनॉड पी

4
क्या आप विशेष रूप से सार्वजनिक डोमेन पर अपना कोड जारी कर सकते हैं, कृपया
स्टॉल्सविक

84

प्रतिबिंब का उपयोग

प्रतिबिंब का उपयोग आमतौर पर उन कार्यक्रमों द्वारा किया जाता है, जिनमें जावा वर्चुअल मशीन में चल रहे अनुप्रयोगों के रनटाइम व्यवहार की जांच या संशोधन करने की क्षमता की आवश्यकता होती है। यह एक अपेक्षाकृत उन्नत विशेषता है और इसका उपयोग केवल उन डेवलपर्स द्वारा किया जाना चाहिए जिनके पास भाषा के मूल सिद्धांतों का एक मजबूत पकड़ है। उस कैविट को ध्यान में रखते हुए, प्रतिबिंब एक शक्तिशाली तकनीक है और अनुप्रयोगों को संचालन करने में सक्षम कर सकता है जो अन्यथा असंभव होगा।

व्यापकता सुविधाएँ

एक अनुप्रयोग बाहरी, उपयोगकर्ता-परिभाषित वर्गों का उपयोग उनके पूर्ण-योग्य नामों का उपयोग करके अस्थिरता वस्तुओं का उदाहरण बनाकर कर सकता है। क्लास ब्राउजर और विजुअल डेवलपमेंट एनवायरनमेंट एक क्लास ब्राउजर को क्लासेस के सदस्यों की गणना करने में सक्षम होना चाहिए। डेवलपर को सही कोड लिखने में सहायता करने के लिए दृश्य विकास वातावरण प्रतिबिंब में उपलब्ध प्रकार की जानकारी का उपयोग करने से लाभ उठा सकता है। डिबगर और टेस्ट टूल डीबगर्स को कक्षाओं में निजी सदस्यों की जांच करने में सक्षम होना चाहिए। टेस्ट हार्नेस एक कक्षा में परिभाषित खोज सेट एपीआई को व्यवस्थित रूप से कॉल करने के लिए प्रतिबिंब का उपयोग कर सकते हैं, एक परीक्षण सूट में उच्च स्तर के कोड कवरेज को सुनिश्चित करने के लिए।

प्रतिबिंब की कमियां

प्रतिबिंब शक्तिशाली है, लेकिन अंधाधुंध उपयोग नहीं किया जाना चाहिए। यदि प्रतिबिंब का उपयोग किए बिना एक ऑपरेशन करना संभव है, तो इसका उपयोग करने से बचने के लिए बेहतर है। प्रतिबिंब के माध्यम से कोड तक पहुंचते समय निम्नलिखित चिंताओं को ध्यान में रखा जाना चाहिए।

  • प्रदर्शन ओवरहेड

क्योंकि प्रतिबिंब में वे प्रकार शामिल होते हैं जो गतिशील रूप से हल किए जाते हैं, कुछ जावा वर्चुअल मशीन अनुकूलन नहीं किए जा सकते हैं। नतीजतन, चिंतनशील संचालन में उनके गैर-चिंतनशील समकक्षों की तुलना में धीमी गति से प्रदर्शन होता है और इसे कोड के वर्गों में टाला जाना चाहिए, जिन्हें प्रदर्शन-संवेदनशील अनुप्रयोगों में अक्सर कहा जाता है।

  • सुरक्षा प्रतिबंध

प्रतिबिंब को एक रनटाइम अनुमति की आवश्यकता होती है जो एक सुरक्षा प्रबंधक के तहत चलने पर मौजूद नहीं हो सकती है। यह कोड के लिए एक महत्वपूर्ण विचार है जिसे प्रतिबंधित सुरक्षा संदर्भ में चलाना होता है, जैसे कि एप्लेट में।

  • आंतरिक का एक्सपोजर

चूंकि प्रतिबिंब गैर-चिंतनशील कोड में उन कार्यों को करने की अनुमति देता है जो गैर-चिंतनशील कोड में गैरकानूनी होंगे, जैसे कि निजी क्षेत्रों और विधियों तक पहुंचना, प्रतिबिंब के उपयोग से अप्रत्याशित दुष्प्रभाव हो सकते हैं, जो कोड की शिथिलता को प्रस्तुत कर सकते हैं और पोर्टेबिलिटी को नष्ट कर सकते हैं। चिंतनशील कोड अमूर्तता को तोड़ता है और इसलिए मंच के उन्नयन के साथ व्यवहार को बदल सकता है।

स्रोत: परावर्तन एपीआई


44

प्रतिबिंब एक कोड या कोड के साथ काम करने की अनुमति देने के लिए एक महत्वपूर्ण तंत्र है जो शायद अभी तक नहीं लिखा गया है!

उदाहरण के लिए अपनी विशिष्ट web.xml फ़ाइल लें। इसमें सर्वलेट तत्वों की एक सूची होगी, जिसमें नेस्टेड सर्वलेट-क्लास तत्व शामिल हैं। सर्वलेट कंटेनर web.xml फ़ाइल को संसाधित करेगा, और प्रतिबिंब के माध्यम से प्रत्येक सर्वलेट वर्ग का एक नया उदाहरण बनाएगा।

एक अन्य उदाहरण XML पार्सिंग (JAXP) के लिए जावा एपीआई होगा । जहां एक XML पार्सर प्रदाता प्रसिद्ध सिस्टम गुणों के माध्यम से 'प्लग-इन' है, जो प्रतिबिंब के माध्यम से नए उदाहरणों का निर्माण करने के लिए उपयोग किया जाता है।

और अंत में, सबसे व्यापक उदाहरण वसंत है जो प्रतिबिंब का उपयोग अपनी फलियां बनाने के लिए करता है, और इसके भारी उपयोग के लिए


36

प्रत्येक भाषा प्रतिबिंब का समर्थन नहीं करती है लेकिन सिद्धांत आमतौर पर भाषाओं में समान होते हैं जो इसका समर्थन करते हैं।

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

यह बहुत सारी स्थितियों में उपयोगी है। हर जगह आप अपने कोड में कक्षाओं में गतिशील रूप से प्लग करने में सक्षम होना चाहते हैं। लोट्स ऑफ़ ऑब्जेक्ट रिलेशनल मैपर्स डेटाबेस से ऑब्जेक्ट्स को इंस्टेंट करने में सक्षम होने के लिए प्रतिबिंब का उपयोग करते हैं, बिना अग्रिम में यह जाने कि वे किन वस्तुओं का उपयोग करने जा रहे हैं। प्लग-इन आर्किटेक्चर एक अन्य स्थान है जहां प्रतिबिंब उपयोगी है। कोड को गतिशील रूप से लोड करने और यह निर्धारित करने में सक्षम होने के नाते कि वहाँ हैं जो उन स्थितियों में एक प्लगइन के रूप में उपयोग करने के लिए सही इंटरफ़ेस को लागू करते हैं।


मुझे डीबी में मौजूद डेटा के आधार पर वस्तुओं को तत्काल करने की आवश्यकता है। मेरा मानना ​​है कि आप यही कह रहे हैं। नमूना कोड मुझे बहुत मदद करेगा। अग्रिम में धन्यवाद।
एटम

34

परावर्तन नई वस्तुओं की तात्कालिकता, विधियों के आह्वान, और इसके संचालन के पूर्व ज्ञान के बिना गतिशील रूप से समय पर कक्षा चर पर संचालन / सेट करने की अनुमति देता है।

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

ऊपर के उदाहरण में अशक्त पैरामीटर वह वस्तु है जिस पर आप विधि लागू करना चाहते हैं। यदि विधि स्थिर है तो आप अशक्त आपूर्ति करते हैं। यदि विधि स्थिर नहीं है, तो आह्वान करते समय आपको अशक्त के बजाय एक वैध MyObject उदाहरण की आपूर्ति करने की आवश्यकता है।

प्रतिबिंब आपको किसी वर्ग के निजी सदस्य / विधियों तक पहुँचने की अनुमति देता है:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • कक्षाओं के निरीक्षण के लिए (यह भी आत्मनिरीक्षण के रूप में जानते हैं) आपको प्रतिबिंब पैकेज ( java.lang.reflect) को आयात करने की आवश्यकता नहीं है । क्लास मेटाडेटा के माध्यम से पहुँचा जा सकता है java.lang.Class

परावर्तन एक बहुत शक्तिशाली एपीआई है, लेकिन अगर यह अतिरिक्त समय में सभी प्रकारों को हल करता है, तो यह एप्लिकेशन को धीमा कर सकता है।


21

जावा परावर्तन काफी शक्तिशाली है और बहुत उपयोगी हो सकता है। जावा परावर्तन , संकलित समय पर वर्गों, विधियों आदि के नामों को जाने बिना , रनटाइम के दौरान कक्षाओं, इंटरफेस, फ़ील्ड और विधियों का निरीक्षण करना संभव बनाता है । प्रतिबिंब का उपयोग करके नई वस्तुओं को त्वरित करना, तरीकों को लागू करना और फ़ील्ड मान प्राप्त करना / सेट करना भी संभव है

एक त्वरित जावा परावर्तन उदाहरण आपको यह दिखाने के लिए कि प्रतिबिंब का उपयोग क्या दिखता है:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

यह उदाहरण MyObject नामक कक्षा से क्लास ऑब्जेक्ट प्राप्त करता है। क्लास ऑब्जेक्ट का उपयोग करके उदाहरण से उस क्लास में विधियों की एक सूची प्राप्त होती है, विधियों को पुनरावृत्त करता है और उनके नामों को प्रिंट करता है।

वास्तव में यह सब कैसे यहाँ समझाया गया है

संपादित करें : लगभग 1 वर्ष के बाद मैं इस उत्तर को संपादित कर रहा हूं क्योंकि प्रतिबिंब के बारे में पढ़ते हुए मुझे प्रतिबिंब के कुछ और उपयोग मिले।

  • वसंत सेम विन्यास का उपयोग करता है जैसे:


<bean id="someID" class="com.example.Foo">
    <property name="someField" value="someValue" />
</bean>

जब स्प्रिंग संदर्भ इस <सेम> तत्व को संसाधित करता है, तो वह उस क्लास को तत्काल करने के लिए "com.example.Foo" तर्क के साथ Class.forName (स्ट्रिंग) का उपयोग करेगा।

यह फिर <संपत्ति> तत्व के लिए उपयुक्त सेटर प्राप्त करने के लिए प्रतिबिंब का उपयोग करेगा और इसके मूल्य को निर्दिष्ट मूल्य पर सेट करेगा।

  • जूनिट विशेष रूप से निजी / संरक्षित विधियों के परीक्षण के लिए प्रतिबिंब का उपयोग करता है।

निजी तरीकों के लिए,

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

निजी क्षेत्रों के लिए,

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

21

उदाहरण:

उदाहरण के लिए एक दूरस्थ अनुप्रयोग लें जो आपके एप्लिकेशन को एक वस्तु देता है जिसे आप उनके एपीआई तरीकों का उपयोग करके प्राप्त करते हैं। अब ऑब्जेक्ट के आधार पर आपको किसी प्रकार की गणना करने की आवश्यकता हो सकती है।

प्रदाता गारंटी देता है कि वस्तु 3 प्रकार की हो सकती है और हमें किस प्रकार की वस्तु के आधार पर गणना करने की आवश्यकता है।

इसलिए हम 3 वर्गों में लागू कर सकते हैं, जिनमें से प्रत्येक में एक अलग तर्क होता है। जाहिर तौर पर ऑब्जेक्ट जानकारी रनटाइम में उपलब्ध है, इसलिए आप कम्प्यूटेशन कोड को कम्प्यूटेशन करने के लिए नहीं कर सकते हैं, इसलिए प्रतिबिंब का उपयोग उस वर्ग के ऑब्जेक्ट को तुरंत करने के लिए किया जाता है, जिस पर आपको कम्प्यूट आधारित प्रदर्शन करने की आवश्यकता होती है प्रदाता से प्राप्त वस्तु।


मुझे कुछ इसी तरह की जरूरत है .. एक उदाहरण मुझे बहुत मदद करेगा क्योंकि मैं अवधारणाओं को प्रतिबिंबित करने के लिए नया हूं ..
एटम

2
मैं भ्रमित हूं: क्या आप instanceofरनटाइम पर ऑब्जेक्ट प्रकार निर्धारित करने के लिए उपयोग नहीं कर सकते हैं ?
ndm13

19

प्रतिबिंब के लिए सरल उदाहरण। शतरंज के खेल में, आप यह नहीं जानते हैं कि रन टाइम में उपयोगकर्ता द्वारा क्या स्थानांतरित किया जाएगा। प्रतिबिंब का उपयोग उन तरीकों को कॉल करने के लिए किया जा सकता है जो पहले से ही रन टाइम पर कार्यान्वित किए जाते हैं:

public class Test {

    public void firstMoveChoice(){
        System.out.println("First Move");
    } 
    public void secondMOveChoice(){
        System.out.println("Second Move");
    }
    public void thirdMoveChoice(){
        System.out.println("Third Move");
    }

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
        Test test = new Test();
        Method[] method = test.getClass().getMethods();
        //firstMoveChoice
        method[0].invoke(test, null);
        //secondMoveChoice
        method[1].invoke(test, null);
        //thirdMoveChoice
        method[2].invoke(test, null);
    }

}

18

परावर्तन एक एपीआई है जिसका उपयोग रनटाइम के दौरान तरीकों, कक्षाओं, इंटरफेस के व्यवहार की जांच करने या संशोधित करने के लिए किया जाता है।

  1. प्रतिबिंब के लिए आवश्यक कक्षाएं नीचे दी गई हैं java.lang.reflect package
  2. प्रतिबिंब हमें उस वर्ग के बारे में जानकारी देता है जिसमें कोई वस्तु होती है और उस वर्ग की विधियां भी होती हैं जिन्हें वस्तु का उपयोग करके निष्पादित किया जा सकता है।
  3. परावर्तन के माध्यम से हम उनके साथ उपयोग किए गए एक्सेस स्पेसियर की परवाह किए बिना रनटाइम पर तरीकों को लागू कर सकते हैं।

java.langऔर java.lang.reflectसंकुल जावा प्रतिबिंब के लिए कक्षाएं प्रदान करते हैं।

प्रतिबिंब के बारे में जानकारी प्राप्त करने के लिए इस्तेमाल किया जा सकता है -

  1. क्लास उस getClass()विधि का उपयोग किया जाता है, जिस कक्षा का नाम किसी वस्तु से है।

  2. कंस्ट्रक्टर्सgetConstructors() विधि वर्ग जो करने के लिए एक वस्तु अंतर्गत आता है की सार्वजनिक कंस्ट्रक्टर्स प्राप्त करने के लिए प्रयोग किया जाता है।

  3. विधियाँ उस getMethods()विधि का उपयोग उस वर्ग की सार्वजनिक विधियों को प्राप्त करने के लिए किया जाता है जिसमें कोई वस्तु होती है।

प्रतिबिंब एपीआई मुख्य रूप में प्रयोग किया जाता है:

आईडीई (इंटीग्रेटेड डेवलपमेंट एनवायरनमेंट) जैसे एक्लिप्स, माय एक्लिप्स, नेटबीन्स आदि
डीबगर और टेस्ट टूल्स आदि।

प्रतिबिंब का उपयोग करने के लाभ:

एक्स्टेंसिबिलिटी फीचर्स: एक एप्लीकेशन बाहरी, यूजर-डिफाइन्ड क्लासेस का उपयोग करके पूरी तरह से योग्य नामों का उपयोग करके एक्स्टेंसिबिलिटी ऑब्जेक्ट्स का उदाहरण बना सकता है।

डिबगिंग और परीक्षण उपकरण: डिबगर्स कक्षाओं में निजी सदस्यों की जांच करने के लिए प्रतिबिंब की संपत्ति का उपयोग करते हैं।

कमियां:

प्रदर्शन ओवरहेड: चिंतनशील संचालन में उनके गैर-चिंतनशील समकक्षों की तुलना में धीमी गति से प्रदर्शन होता है, और उन्हें कोड के वर्गों में बचा जाना चाहिए जिन्हें प्रदर्शन-संवेदनशील अनुप्रयोगों में अक्सर कहा जाता है।

इंटरनल्स का एक्सपोजर: रिफ्लेक्टिव कोड अमूर्तता को तोड़ता है और इसलिए प्लेटफॉर्म के उन्नयन के साथ व्यवहार में बदलाव हो सकता है।

Ref: जावा परावर्तन javarevisited.blogspot.in


4
मैं कमियों को जोड़ूंगा " यह रीफैक्टरिंग को तोड़ता है "। मेरे लिए यह मुख्य कारण है कि जितना संभव हो उतना प्रतिबिंब से बचें।
शांतिबेल

तो यह हमें अनुमति देता है (उदाहरण के लिए), हमारे पास मौजूद कक्षाओं का निरीक्षण करने के लिए (चाहे हमारे पास उनके उदाहरण हैं या नहीं), सही है? इसका मतलब है कि, उनके तरीके या निर्माणकर्ता प्राप्त करें और नए उदाहरण बनाने / उनका उपयोग करने के लिए उनका उपयोग करें। अगर व्यवहार पहले से ही अलग कोड के साथ है, तो हम "प्रोग्राम व्यवहार में बदलाव" क्यों कहते हैं? इसे "प्रतिबिंब" क्यों कहा जाता है? धन्यवाद
फर्नांडो गैब्रियल 21

15

मेरी समझ के अनुसार:

प्रतिबिंब प्रोग्रामर को गतिशील रूप से प्रोग्राम में संस्थाओं तक पहुंचने की अनुमति देता है। यदि प्रोग्रामर किसी वर्ग या इसके तरीकों के बारे में अनभिज्ञ है, तो किसी एप्लिकेशन को कोड करते समय, वह प्रतिबिंब का उपयोग करके इस तरह के क्लास को गतिशील रूप से (रन टाइम में) उपयोग कर सकता है।

यह अक्सर उन परिदृश्यों में उपयोग किया जाता है जहां एक वर्ग का नाम अक्सर बदलता है। यदि ऐसी स्थिति उत्पन्न होती है, तो प्रोग्रामर के लिए आवेदन को फिर से लिखना और कक्षा का नाम बार-बार बदलना जटिल है।

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


15

प्रतिबिंब कार्यों का एक समूह है जो आपको अपने कार्यक्रम की रनटाइम जानकारी तक पहुंचने और इसे व्यवहार (कुछ सीमाओं के साथ) को संशोधित करने की अनुमति देता है।

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

उदाहरण के लिए C # में आप एक असेंबली (-dll) को लोड कर सकते हैं, एक रनटाइम में इसे जांच सकते हैं, कक्षाओं के माध्यम से नेविगेट कर सकते हैं और जो आपको मिला है उसके अनुसार कार्रवाई कर सकते हैं। यह आपको रनटाइम पर एक कक्षा का एक उदाहरण बनाने देता है, इसकी विधि लागू करता है, आदि।

यह कहां उपयोगी हो सकता है? हर बार उपयोगी नहीं है, लेकिन ठोस स्थितियों के लिए। उदाहरण के लिए, आप इसका उपयोग लॉगिंग उद्देश्यों के लिए वर्ग का नाम प्राप्त करने के लिए कर सकते हैं, गतिशील रूप से घटनाओं के लिए हैंडलर बनाने के लिए जो किसी कॉन्फ़िगरेशन फ़ाइल पर निर्दिष्ट है और इसी तरह ...


11

मैं केवल उन सभी को कुछ बिंदु जोड़ना चाहता हूं जो सूचीबद्ध थे।

प्रतिबिंब एपीआई के साथ आप toString()किसी भी वस्तु के लिए सार्वभौमिक विधि लिख सकते हैं ।

यह डिबगिंग में उपयोगी है।

यहाँ कुछ उदाहरण है:

class ObjectAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object's class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}

11

परावर्तन वस्तु को उनके स्वरूप को देखने के लिए करना है। इस तर्क का प्रतिबिंब से कोई लेना देना नहीं है। वास्तव में, यह "आत्म-पहचान" की क्षमता है।

प्रतिबिंब स्वयं ऐसी भाषाओं के लिए एक शब्द है, जिसमें जावा और C # के रूप में आत्म-ज्ञान और आत्म-संवेदन की क्षमता का अभाव है। क्योंकि उनके पास आत्म-ज्ञान की क्षमता नहीं है, जब हम यह देखना चाहते हैं कि यह कैसा दिखता है, तो हमारे पास एक और बात होनी चाहिए कि यह कैसा दिखता है। उत्कृष्ट गतिशील भाषाएं जैसे रूबी और पायथन अन्य व्यक्तियों की सहायता के बिना अपने स्वयं के प्रतिबिंब का अनुभव कर सकते हैं। हम कह सकते हैं कि जावा की वस्तु यह नहीं देख सकती है कि यह बिना दर्पण के कैसा दिखता है, जो कि परावर्तन वर्ग की वस्तु है, लेकिन पायथन में कोई वस्तु इसे बिना दर्पण के भी देख सकती है। इसलिए हमें जावा में प्रतिबिंब की आवश्यकता है।


प्रकार (), आइंस्टीन (), कॉल करने योग्य (), dir () और getattr ()। .... ये
पाइथोनिक

9

जावा प्रलेखन पृष्ठ से

java.lang.reflectपैकेज कक्षाओं और वस्तुओं के बारे में चिंतनशील जानकारी प्राप्त करने के लिए कक्षाएं और इंटरफेस प्रदान करता है। प्रतिबिंब, सुरक्षा प्रतिबंधों के भीतर अपने अंतर्निहित समकक्षों पर कार्य करने के लिए भारित वर्गों के क्षेत्रों, विधियों और निर्माणकर्ताओं और प्रतिबिंबित क्षेत्रों, विधियों और निर्माणकर्ताओं के बारे में जानकारी के लिए प्रोग्रामेटिक पहुंच की अनुमति देता है।

AccessibleObjectयदि आवश्यक हो तो एक्सेस चेक के दमन की अनुमति देता ReflectPermissionहै।

इस पैकेज में कक्षाएं, साथ साथ java.lang.Classइस तरह के डिबगर, दुभाषियों, वस्तु निरीक्षकों, वर्ग ब्राउज़रों, और इस तरह के रूप में सेवाओं के रूप में अनुप्रयोगों को समायोजित Object Serializationऔर JavaBeansया तो एक लक्ष्य वस्तु की जनता के सदस्यों के लिए है कि जरूरत एक्सेस (अपने क्रम वर्ग के आधार पर) या सदस्यों द्वारा घोषित एक दिया गया वर्ग

इसमें निम्न कार्यक्षमता शामिल है।

  1. कक्षा वस्तुओं को प्राप्त करना,
  2. एक वर्ग (खेतों, विधियों, निर्माणकर्ताओं) के गुणों की जांच करना,
  3. फ़ील्ड मान सेट करना और प्राप्त करना,
  4. आमंत्रित करने के तरीके,
  5. वस्तुओं के नए उदाहरण बनाना।

कक्षा द्वारा उजागर तरीकों के लिए इस दस्तावेज़ीकरण लिंक पर एक नज़र डालें Class

इस लेख से (डेनिस सोसनोस्की, राष्ट्रपति, सोसनोस्की सॉफ्टवेयर सॉल्यूशंस, इंक) और इस लेख (सुरक्षा-अन्वेषण पीडीएफ) से:

मैं प्रतिबिंब का उपयोग करने की तुलना में काफी कमियां देख सकता हूं

परावर्तन का उपयोगकर्ता:

  1. यह गतिशील रूप से लिंकिंग प्रोग्राम घटकों का बहुत बहुमुखी तरीका प्रदान करता है
  2. यह पुस्तकालयों को बनाने के लिए उपयोगी है जो वस्तुओं के साथ बहुत सामान्य तरीके से काम करते हैं

प्रतिबिंब की कमियां:

  1. जब फ़ील्ड और विधि पहुँच के लिए उपयोग किया जाता है तो प्रतिबिंब प्रत्यक्ष कोड की तुलना में बहुत धीमा होता है।
  2. यह अस्पष्ट कर सकता है कि वास्तव में आपके कोड के अंदर क्या चल रहा है
  3. यह स्रोत कोड को दरकिनार कर रखरखाव समस्याएं पैदा कर सकता है
  4. परावर्तन कोड भी संबंधित प्रत्यक्ष कोड की तुलना में अधिक जटिल है
  5. यह डेटा सुरक्षा और टाइप सुरक्षा जैसे प्रमुख जावा सुरक्षा बाधाओं का उल्लंघन करने की अनुमति देता है

सामान्य दुर्व्यवहार:

  1. प्रतिबंधित कक्षाओं का लोडिंग,
  2. प्रतिबंधित वर्ग के निर्माणकर्ताओं, विधियों या क्षेत्रों के संदर्भों को प्राप्त करना
  3. नए ऑब्जेक्ट इंस्टेंसेस का निर्माण, विधियों का आह्वान, प्रतिबंधित वर्ग के क्षेत्र मूल्यों को प्राप्त करना या स्थापित करना।

परावर्तन सुविधा के दुरुपयोग के संबंध में इस SE प्रश्न पर एक नज़र:

मैं जावा में एक निजी क्षेत्र कैसे पढ़ सकता हूं?

सारांश:

सिस्टम कोड के भीतर से किए गए अपने कार्यों का असुरक्षित उपयोग भी आसानी से एक जावा सुरक्षा मोड l का समझौता हो सकता हैइसलिए इस सुविधा का संयम से उपयोग करें


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

9

जैसा कि नाम से ही पता चलता है कि यह दर्शाता है कि यह उदाहरण के लिए किस विधि को धारण करता है, इत्यादि, इसके अलावा सुविधा प्रदान करने के लिए रन टाइम पर गतिशील रूप से उदाहरण बनाने के लिए।

यह कई चौखटे और लकड़ी के नीचे अनुप्रयोग द्वारा वास्तव में कोड को जाने बिना सेवाओं को लागू करने के लिए उपयोग किया जाता है।


7

प्रतिबिंब आपको अधिक सामान्य कोड लिखने की क्षमता देता है। यह आपको रनटाइम पर एक ऑब्जेक्ट बनाने और रनटाइम पर इसकी विधि को कॉल करने की अनुमति देता है। इसलिए कार्यक्रम को अत्यधिक मानकीकृत किया जा सकता है। यह वस्तु और वर्ग को बाहरी दुनिया के संपर्क में आने वाले चर और विधि का पता लगाने की अनुमति देता है।


6

Reflectionकई उपयोग हैं । मैं जिसके साथ अधिक परिचित हूं, वह मक्खी पर कोड बनाने में सक्षम है।

IE: किसी भी डेटा (xml / array / sql परिणाम / हार्डकोड / आदि) के आधार पर डायनामिक कक्षाएं, फ़ंक्शंस, कंस्ट्रक्टर -)


1
यदि आप SQL परिणाम या XML फ़ाइल आदि से उत्पन्न कोड का सिर्फ एक असामान्य उदाहरण देते हैं तो यह उत्तर बहुत बेहतर होगा
ThisClark

कोई दिक्कत नहीं है। मैंने एक विंडोज़ एप्लिकेशन में प्रतिबिंब का उपयोग किया है जो गतिशील रूप से डेटाबेस से लिए गए XML पर आधारित इंटरफ़ेस उत्पन्न करता है।
Ess Kay

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

3

मैं इस सवाल का जवाब उदाहरण के साथ देना चाहता हूं। सबसे पहले Hibernateप्रोजेक्ट रनिंग एप्लिकेशन और दृढ़ता स्टोर के बीच की खाई को पाटने के लिए स्टेटमेंट Reflection APIजेनरेट करने के लिए उपयोग करता है CRUD। जब डोमेन में चीजें बदल जाती हैं, तो Hibernateउन्हें डेटा स्टोर और इसके विपरीत जारी रखने के लिए उनके बारे में जानना होगा।

वैकल्पिक रूप से काम करता है Lombok Project। यह बस संकलन समय पर कोड इंजेक्ट करता है, जिसके परिणामस्वरूप कोड आपके डोमेन कक्षाओं में डाला जाता है। (मुझे लगता है कि यह गेटर्स और सेटर के लिए ठीक है)

Hibernateचुना reflectionक्योंकि यह एक आवेदन के लिए निर्माण प्रक्रिया पर कम से कम प्रभाव पड़ता है।

और जावा 7 से हमारे पास है MethodHandles, जो काम करता है Reflection API। प्रोजेक्टर्स में, लकड़हारे के साथ काम करने के लिए हम सिर्फ अगले कोड को कॉपी-पेस्ट करते हैं:

Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());

क्योंकि इस मामले में टाइपो-एरर करना कठिन है।


3

जैसा कि मुझे उदाहरण द्वारा व्याख्या करना सबसे अच्छा लगता है और कोई भी उत्तर ऐसा नहीं लगता है ...

प्रतिबिंबों का उपयोग करने का एक व्यावहारिक उदाहरण जावा में लिखा गया जावा भाषा सर्वर या पीएचपी में लिखा गया PHP भाषा सर्वर होगा, आदि भाषा सर्वर आपके IDE क्षमताओं को स्वत: पूर्णता, जंप टू डेफिनिशन, संदर्भ मदद, हाइटिंग प्रकार और बहुत कुछ देता है। सभी संभावित नामों को दिखाने के लिए सभी संभावित नाम दिखाने के लिए (जैसा कि आप स्वत: पूर्ण हो सकते हैं), जैसा कि आप भाषा सर्वर टाइप करते हैं, डॉक ब्लॉक और निजी सदस्यों सहित वर्ग के बारे में सब कुछ निरीक्षण करना है। उसके लिए उसे उक्त वर्ग का प्रतिबिंब चाहिए।

एक अलग उदाहरण एक निजी पद्धति का एक इकाई-परीक्षण होगा। ऐसा करने का एक तरीका यह है कि परीक्षण के सेट-अप चरण में एक प्रतिबिंब बनाया जाए और विधि के दायरे को सार्वजनिक किया जाए। बेशक कोई तर्क दे सकता है कि निजी तरीकों का सीधे परीक्षण नहीं किया जाना चाहिए, लेकिन यह बात नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.