2011-05-16 20 views
15

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

एक विधि चुनने का "आसान" तरीका तब होता है जब आप सभी तर्कों के सटीक प्रकार जानते हैं, जिस बिंदु पर आप Class.getDeclaredMethod(String name, Class[] parameterTypes) का उपयोग कर सकते हैं। शायद आपको विधि पहुंच और कक्षा के सुपरक्लास/superinterfaces की जांच करनी है।

लेकिन यह निम्नलिखित मामलों में से किसी को कवर नहीं करता, तो यह एक तरह से बेकार है:

  • मुक्केबाजी/unboxing पुरातन
  • उपप्रकार
  • varargs
  • एक अशक्त तर्क (हो सकता है जो किसी भी प्रकार का, जब तक कि दुभाषिया अन्यथा नहीं जानता; संकलन-समय पर किसी भी अस्पष्टता को कक्षा/इंटरफ़ेस में नल कास्टिंग करके समाप्त किया जाएगा)
  • आदिम प्रकार रूपांतरण (जावा का हिस्सा नहीं, लेकिन स्वीकार्य भाषाओं का संदर्भ - उदा। राइनो जावास्क्रिप्ट जहां सभी नंबरों हैं फ्लोटिंग प्वाइंट, तो जावा कोड एक int लग सकता है, लेकिन फोन करने वाले एक नंबर जो या तो एक int या एक double)

(पहले की एक त्वरित उदाहरण के लिए नीचे देखें में गुजरता तीन)

तो अब मैं अपने ही विधि संकल्प पुस्तकालय लिखने के लिए है ...

इस में सहायता के लिए किसी भी अच्छी तरह से ज्ञात ढांचे पुस्तकालय है?

package com.example.test.reflect; 

import java.lang.reflect.Method; 

public class MethodResolutionTest { 
    public void compute(int i)    { /* implementation... */ } 
    public void compute(Long l)    { /* implementation... */ } 
    public void compute(Object obj)   { /* implementation... */ } 
    public void compute(String... strings) { /* implementation... */ } 

    public static void main(String[] args) { 
     Class<?> cl = MethodResolutionTest.class; 

     /* these succeed */ 
     findAndPrintMethod(cl, "compute", int.class); 
     findAndPrintMethod(cl, "compute", Long.class); 
     findAndPrintMethod(cl, "compute", Object.class); 
     findAndPrintMethod(cl, "compute", String[].class); 

     /* these fail */ 
     findAndPrintMethod(cl, "compute", Integer.class); 
     findAndPrintMethod(cl, "compute", long.class); 
     findAndPrintMethod(cl, "compute", MethodResolutionTest.class); 
     findAndPrintMethod(cl, "compute", String.class, String.class); 
    } 
    private static void findAndPrintMethod(Class<?> objectClass, 
      String methodName, Class<?>... parameterTypes) 
    { 
     try { 
      Method method = findMethod(objectClass, methodName, 
        parameterTypes); 
      System.out.println(method.toString()); 
     } 
     catch (SecurityException e) { 
      e.printStackTrace(); 
     } 
     catch (NoSuchMethodException e) { 
      e.printStackTrace(); 
     } 
    } 
    private static Method findMethod(Class<?> objectClass, 
      String methodName, Class<?>[] parameterTypes) 
     throws SecurityException, NoSuchMethodException 
    { 
     return objectClass.getDeclaredMethod(methodName, parameterTypes); 
    } 
} 
+1

[यह उत्तर उपप्रकारों जैसे आपके कुछ मामलों को संभालता है] (http://stackoverflow.com/questions/2580665/java-getmethod-with-superclass-parameters-in-method/2580699#2580699)। –

+1

@ जोनाथन: मुझे पता है कि Isssignable से है। मुझे उपप्रकार और मुक्केबाजी/अनबॉक्सिंग के साथ काम करने वाला कुछ घर मिला। तब मैंने varargs में शुरू किया और यह बुरा हो गया, और मैंने सोचा, "एक मिनट रुको, मैं यह सब क्यों कर रहा हूँ?" इसलिए मैं विशेष रूप से एक पूर्व-मौजूदा पुस्तकालय की तलाश में हूं। (या कम से कम पूर्व-मौजूदा परीक्षण मामलों का एक अच्छा सेट) अन्यथा मैं इसे अपने आप कर सकता हूं, लेकिन यह एक बड़ा दर्द है। –

+1

जब तक आपको एक मीठी लाइब्रेरी नहीं मिलती, मुझे लगता है कि जो कुछ भी आप करते हैं वह बदसूरत और पढ़ने के लिए कठिन होगा। –

उत्तर

-1

मैं MVEL और गुणों के साथ कुछ सफलता मिली है, लेकिन मैं याद नहीं आ रहा है कि क्या यह विधि कॉल प्रेषण कर सकते हैं।

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

+0

हम्म, मैं विभिन्न कारणों से जावा के साथ "अटक गया" हूं, सबसे बड़ी एक रखरखाव है (एक अलग भाषा जोड़ना महत्वपूर्ण रूप से अन्य डेवलपर्स से सहायता प्राप्त करने की मेरी क्षमता को बाधित करता है) –

2

कॉमन्स beanutils मिलान तरीके खोजने के लिए इस समारोह है: getMatchingAccessibleMethod

यह आदिम प्रकार के साथ काम करता है, लेकिन यह कुछ हद तक indeterministic डॉक्स का कहना है के रूप में है।

+1

ध्यान दें कि 'getMatchingAccessibleMethod' में आदिम मिलान एक तरीका है - पैरामीटर 'Long.class'' foo (long) 'से मेल खाएगा, लेकिन' Long.TYPE' 'foo (long) ' – McDowell

+0

+1 से मेल नहीं खाएगा: @ बेंगेट: अपाचे को कुछ टूल मिलते हैं, शायद नहीं मैं क्या चाहता था, लेकिन कम से कम कुछ। –

3

आप this blog post पढ़ना चाहेंगे और ClassMate देखें। यह आपके लिए सबसे अधिक कामयाबी काम करना चाहिए।

+0

ARGH! तो आशाजनक है, लेकिन यह थोड़ा अलग है - यह सामान्य प्रकार का समाधान करता है, लेकिन विधि समाधान के लिए कुछ भी नहीं करता है। लेकिन कम से कम यह एक शुरुआत है, और मैं शर्त लगाता हूं कि मैं लेखकों को इसे विस्तारित करने के लिए तैयार कर सकता हूं। –

0

अमरूद-चर्चा पर उपयोगकर्ताओं में से एक ने सिफारिश की है कि मैं Mirror library पर विचार करता हूं।

दुर्भाग्य से यह कम से कम वर्तमान में ओवरलोडिंग रिज़ॉल्यूशन को संभाल नहीं करता है।

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