2010-07-08 11 views
27

मेरी वर्तमान प्रोजेक्ट पर, मुझे प्रतिबिंब का उपयोग करके जावा में एक तरह की नकली कॉलबैक प्रणाली बनाने की आवश्यकता महसूस हुई है। हालांकि, मुझे वास्तव में काम करने के लिए मेरे प्रतिबिंब प्राप्त करने में समस्याएं आ रही हैं। गलती कोड इस प्रकार है:जावा: NoSuchMethodException जब विधि स्पष्ट रूप से मौजूद है

public Callback(Object parentObj, String methodName, Class<?>...parameters) 
{ 
    if(parentObj == null) 
     throw new IllegalArgumentException("parentObj cannot be null", new NullPointerException()); 

    Class<?> clazz = parentObj.getClass(); 

    // Trace debugging, see output 
    for(Method m : clazz.getDeclaredMethods()) 
     if(m.getName().equals("myMethod")) System.out.println (m); 

    try { this.method = clazz.getMethod(methodName, parameters); } 
    catch(NoSuchMethodException nsme) { nsme.printStackTrace(); } // Exception caught 
    catch(SecurityException se) { se.printStackTrace(); } 

    this.parentObj = parentObj; 
    this.parameters = parameters; 
} 

जब मैं Callback वस्तु का निर्माण, मैं इस तरह सिंटैक्स का उपयोग कर रहा हूँ:

new Callback(this, "myMethod", boolean.class) 

जब मैं अपने छद्म कॉलबैक बनाने का प्रयास करें, यह NoSuchMethodException पकड़ हिट ब्लॉक। मैंने अपनी विधियों में से किसी एक के आउटपुट को प्रदर्शित करने के लिए ऊपर कुछ ट्रेस डीबगिंग शामिल किया है। आउटपुट:

private void my.package.MyClass.myMethod(boolean) 
java.lang.NoSuchMethodException: my.package.MyClass.myMethod(boolean) 
    at java.lang.Class.getMethod(Class.java:1605) 
    at my.package.other.Callback.<init>(Callback.java:63) 

मुझे समस्या का पता नहीं लगा सका, इसलिए मैंने थोड़ा फायदा उठाने के लिए शिकार करना शुरू कर दिया। सबसे अच्छा मुझे मिल सकता है संकलित जेएआर और रनटाइम के बीच संस्करण संघर्ष का उल्लेख था। हालांकि, MyJar.jar/META-INF/MANIFEST.MF में Created-By: 1.6.0_02 (Sun Microsystems Inc.) शामिल हैं। मेरी परियोजना संकलित करने के लिए मेरा आईडीई C:\Program Files\Java\jdk1.6.0_02\bin\javac.exe चला रहा है। मैं अपने जेएआर चलाने के लिए C:\Program Files\Java\jdk1.6.0_02\bin\java.exe का उपयोग कर रहा हूं।

मुझे नुकसान हुआ है क्यों Class.getMethod दावा कर रहा है कि विधि मौजूद नहीं है, लेकिन Class.getMethods को खोजने में कोई समस्या नहीं है। मदद? :(

+1

यही कारण है कि आप प्रतिबिंब पर भरोसा नहीं करते हैं, जो कि सबसे अच्छा अविश्वसनीय है। – quantumSoup

+0

मैं यह नहीं कहूंगा कि यह अविश्वसनीय है, लेकिन यह जटिल और अक्षम हो सकता है। –

+1

यह आपके संकलक साबित करने वाले किसी चीज़ की तुलना में निश्चित रूप से कम विश्वसनीय है। :-) –

उत्तर

86

आपकी विधि निजी है लेकिन getMethod() केवल सार्वजनिक विधि लौटाती है।

आपको getDeclaredMethod() का उपयोग करने की आवश्यकता है।

+0

हाँ है! यह मुझे सार्वजनिक तरीकों का उपयोग करने के लिए मजबूर किए बिना समस्या को हल करता है। धन्यवाद! –

+3

3 साल बाद ... यह मेरे मामले में बहुत समझ में आता है। हालांकि मैंने http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getMethod(java.lang.String, java.lang पर दोनों विधियों के लिए प्रलेखन पढ़ना शुरू कर दिया। कक्षा ...) और वे ऐसी जानकारी का जिक्र नहीं करते हैं। शायद आप कोड में देखा? आपके लिए अच्छा हैं। +1 – Mzn

+0

दीवार पर मेरे सिर को 2 घंटे तक सीधे टक्कर लगी थी। धन्यवाद दोस्त ! –

0

संस्करण मुद्दा क्रम बनाम संकलन समय पर कारण है कि कर सकते हैं NoSuchMethodException संकलक संस्करणों के बीच एक अंतर नहीं है। यह (अपने मामले में) के संस्करण में एक फर्क है MyClass

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

क्या आप सुनिश्चित हैं कि पैरामीटर आपकी वास्तविक विधि से मेल खाते हैं?

4

getMethod के लिए जावाडोक स्पष्ट नहीं है, लेकिन ऐसा लगता है कि यह उन विधियों के लिए NoSuchMethodException फेंक सकता है जो सार्वजनिक नहीं हैं, और आपकी विधि निजी है।

+2

हाँ, यह है। आपके सुझाव ने कक्षा के लिए स्रोत कोड के माध्यम से मुझे डाला था। 'getMethod' कॉल (निजी)' getMethod0'।'getMethod0' कॉल 'privateGetDeclaredMethods (true)', जहां' true' "' publiclyly' " –

1

आपको कॉल करने के लिए इच्छित विधि के लिए बिल्कुल सही होने के लिए पैरामीटर सूची की आवश्यकता है।

मुझे पता चला है कि प्रतिबिंब करते समय छोटे कदम महत्वपूर्ण हैं क्योंकि संकलक मदद नहीं करता है। एक छोटा सा स्निपेट लिखें जो वास्तव में में विशेष मामले में वास्तव में जिस विधि को आप चाहते हैं उसे आमंत्रित करता है, और फिर जब यह काम करता है, तो इसे यहां ढांचे में सामान्यीकृत करें। मैं पारित पैरामीटर पर ध्यान केंद्रित करेंगे।

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