2012-05-24 5 views
22

में प्रतिबिंब द्वारा जेनेरिक विधि को कॉल करें जावा में प्रतिबिंब द्वारा कस्टम जेनेरिक विधि को कैसे कॉल करें?जावा

class Person 
{ 
    public <T> void print(T t) 
    { 
     System.out.println(t.toString()); 
    } 
} 

उत्तर

20

जेनेरिक्स संकलन समय पर मिट जाता है में खूबसूरती से समझाया गया है, वे केवल संकलक करने के लिए अतिरिक्त जानकारी त्रुटियों निर्धारित करने के लिए प्रदान करते हैं। वे वास्तव में .class फ़ाइल में विधि के हस्ताक्षर को नहीं बदलते हैं।

इसका मतलब है कि आप जावा में प्रतिबिंब द्वारा एक सामान्य विधि को उसी तरह कहते हैं जैसे आप जावा में एक गैर-जेनेरिक विधि कहेंगे, सिवाय इसके कि T का एक प्रकार निर्दिष्ट करने के बजाय, आप Object का एक प्रकार निर्दिष्ट करेंगे।

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

यदि आपको लगता है कि चीजें अपेक्षित काम नहीं कर रही हैं, तो आप संकलित श्रेणी फ़ाइल पर javap चला सकते हैं ताकि यह सत्यापित किया जा सके कि आप तर्क सूची में सही ऑब्जेक्ट्स का उपयोग कर रहे हैं। यह संभव हो सकता है कि यदि आप <T extends List> सामान्य जेनेरिक हस्ताक्षर निर्दिष्ट करते हैं, तो परिणामस्वरूप पैरामीटर ऑब्जेक्ट वास्तव में List ऑब्जेक्ट हो सकता है।

10

यह मेरे लिए काम करता है।

Method method = Person.class.getMethod("print", Object.class); 

method.invoke(new Person(), "this is a string"); 
method.invoke(new Person(), 273); 
method.invoke(new Person(), new Object()); 

मुद्रण

this is a string 
273 
[email protected] 
बेशक

इस के पीछे सिद्धांत @Edwin's answer.

4

बिंदु एडविन के जवाब है, जहां हम प्रयोग कर रहे हैं में दी गई यह बताने के लिए एक सामान्य प्रकार में लागू होता है: यदि आप

GenericHibernateDao<T extends Serializable> 

की तरह एक वर्ग है, और एक विधि है

public T save(T entity) {}; 

आह्वान करने के लिए

Method method = GenericHibernateDao.class.getMethod(methodName, Serializable.class); 

और n: प्रतिबिंब का उपयोग कर आप, Serializable वर्ग का उपयोग करने के यानी सेव विधि, आप उपयोग करने की आवश्यकता ऑब्जेक्ट.क्लास पैरामीटर के रूप में, क्योंकि हम

<T extends Serializable> 
का उपयोग कर रहे हैं