2012-08-12 13 views
6

तो, मेरे पास एक अजीब मुद्दा है। यह अभिव्यक्ति: method.invoke(target, null) java.lang.IllegalArgumentException फेंकता है: तर्कvarargs और शून्य तर्क

समस्या यह है कि इस अभिव्यक्ति गहरे अंदर हाइबरनेट (BasicPropertyAccessor $ BasicGetter सटीक होना करने के लिए) है और मुझे लगता है कि यह ठीक से काम करना चाहिए (यह हाल ही में जब तक किया था की गलत संख्या)

मैंने इस समस्या को ग्रहण में डीबग किया और वास्तव में, यदि मैं (प्रदर्शन दृश्य में) कॉल method.invoke(target) या method.invoke(target, (Object[]) null) सब कुछ ठीक काम करता है। मुझे यकीन है कि मेरी कक्षा में यह गेटर है और इसमें कोई तर्क नहीं है। तो ... सवाल यह है कि क्या चल रहा है ?!

संपादित करें:

  • विधि कहा गेटर
  • लक्ष्य को java.lang.reflect.Method और अंक का एक उदाहरण है सार्वजनिक एक्स getX() गेटर
  • साथ वर्ग का एक उदाहरण है JDK 1.6.0_31
  • हाइबरनेट में कोड (BasicPropertyAccessor: 143):

    public Object get(Object target) throws HibernateException { 
        try { 
         return method.invoke(target, null); 
        } 
        catch{ ... } 
    } 
    
+0

आप किस विधि का आह्वान करने की कोशिश कर रहे हैं? – Jeffrey

+0

session.flush(): पी लेकिन अंत में, हाइबरनेट गेटटर – mabn

+0

को आमंत्रित करने का प्रयास कर रहा है विधि का हस्ताक्षर क्या है? – Bohemian

उत्तर

8

जब आप एक varargs पद्धति के लिए एक null मान पास, यह दो चीजों में से एक के रूप में व्याख्या की जा सकती:

  • एक null सरणी
  • एक तत्व जो null है के साथ एक सरणी।

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

कोई तर्क के साथ विधियों का आह्वान करते समय, आप या तो Method.invoke 0 के साथ एक सरणी पास कर सकते हैं तत्वों, बिना किसी अतिरिक्त तर्क (जो एक खाली सरणी में परिणाम होगा), या एक null सरणी:

public class MethodInvoke { 
    public static void noParams() { 
     System.out.println("noParams called"); 
    } 

    public static void main(String[] args) throws NoSuchMethodException, 
      SecurityException, IllegalAccessException, 
      IllegalArgumentException, InvocationTargetException { 
     Method noParams = MethodInvoke.class.getMethod("noParams"); 
     Object target = null; 
     noParams.invoke(target, new Object[0]); 
     noParams.invoke(target); 
     noParams.invoke(target, null); 
     noParams.invoke(target, (Object[]) null); 
     noParams.invoke(target, (Object) null); // wrong number of arguments 
    } 
} 

क्या हो रहा प्रतीत होता है कि method.invoke(target, null)method.invoke(target, (Object) null) के रूप में व्याख्या की जा रही है। जावा के व्यवहार के साथ यह असंगत है।

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

मैंने यह भी देखा कि हाइबरनेट के नए संस्करण में उन्होंने स्पष्ट रूप से null से Object[] पर कास्ट किया।

+0

पर स्निपेट जोड़ा है, मैंने मैवेन रिपोजिटरी, पुनर्निर्मित डेटाबेस, वर्कस्पेस, प्रोजेक्ट और क्लासपाथ फाइलों को मंजूरी दे दी है और यह काम करना शुरू कर दिया है। मुझे अभी भी कोई सुराग नहीं है कि यह इतना अजीब क्यों व्यवहार करता था। – mabn

+0

@mabn हाँ, यह वास्तव में एक अजीब बग है। कम से कम अगर यह आपको फिर से काटने के लिए वापस आता है तो आपको पता चलेगा कि – Jeffrey

0

तो विधि के हस्ताक्षर public X getX() है तो कोई मापदंड हैं, तो यह इस तरह कहते हैं:

method.invoke(target); 

invoke() विधि के पहले पैरामीटर उदाहरण है जिस पर विधि आह्वान करने के लिए है ।

ध्यान दें कि varargs तरीकों के लिए, जिस तरह से आप मापदंडों को कॉमा द्वारा जैसे method(a, b, c) निर्दिष्ट method(new Object[]{a, b, c} के लिए वाक्यात्मक चीनी है: औपचारिक पैरामीटर प्रकार Object[] है।

+0

क्या करना चाहिए इससे कोई फर्क नहीं पड़ता। मेरा उत्तर देखें – Jeffrey

+0

मैं आपके द्वारा प्रदान की गई अभिव्यक्ति को नहीं बदल सकता, हाइबरनेट उस पर हमला करता है। – mabn

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