2012-02-06 21 views
6

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

T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject); 
// If it's null, let's assign something assignable. 
if (resultNotNull == null) { 
    if (resultNotNull.getClass().isAssignableFrom(Long.class)) { 
     resultNotNull = (T) Long.valueOf(-1); 
    } else if (resultNotNull.getClass().isAssignableFrom(String.class)) { 
     resultNotNull = (T) "NOTHING"; 
    } 
} 

लेकिन ज़ाहिर है, अगर 'resultNotNull == अशक्त', हम नहीं कर सकते:

है, के बाद प्रतिबिंब द्वारा विधि बुला, मैं कुछ इस तरह अमल करना चाहते हैं अपवाद प्राप्त किए बिना 'resultNotNull.getClass()' पर कॉल करें।

जेनेरिक प्रकार के आधार पर डिफ़ॉल्ट मान को असाइन करने के तरीके पर कोई विचार?

पूरे कोड कुछ इस तरह होगा:

public class ReflectionTest { 
    public class Class1ok { 
     public Long method() { return Long.valueOf(1); } 
    } 
    public class Class1null { 
     public Long method() { return null; } // It returns null 
    } 
    public class Class2ok { 
     public String method() { return "SOMETHING"; } 
    } 

    public static void main(String[] args) { 
     ReflectionTest test = new ReflectionTest(); 

     Long notNullValue1 
      = test.methodReturnNotNull(Class1ok.class); // 1 
     Long notNullValue2 
      = test.methodReturnNotNull(Class1null.class); // -1, not null 
     String notNullValue3 
      = test.methodReturnNotNull(Class2ok.class); // "SOMETHING" 
    } 

    public <T> T methodReturnNotNull(Class theClass) { 
     T resultNotNull = null; 
     try { 
      Object theObject = theClass.newInstance(); 
      Method methodThatCanReturnNull = theClass.getMethod("method"); 
      resultNotNull = (T) methodThatCanReturnNull.invoke(theObject); 
     } catch (Exception e) { 
      // Meh. 
     } 

     // If it's null, assign something assignable. 
     if (resultNotNull == null) { 
      if (resultNotNull.getClass().isAssignableFrom(Long.class)) { 
       resultNotNull = (T) Long.valueOf(-1); 
      } else if (resultNotNull.getClass().isAssignableFrom(String.class)) { 
       resultNotNull = (T) "NOTHING"; 
      } 
     } 
     return resultNotNull; 
    } 
} 

उत्तर

3

आप getReturnType() का उपयोग कर सकते हैं;

private static final Map<Class, Object> replacementForNull = new HashMap<>(); 
static { 
    replacementForNull.put(String.class, "NOTHING"); 
    replacementForNull.put(Long.class, 1L); 
} 


Method reflectionMethodThatCanReturnNull = ... 
T resultNotNull = (T) reflectionMethodThatCanReturnNull.invoke(anObject); 
// If it's null, let's assign something assignable. 
if (resultNotNull == null) { 
    Class returnType = reflectionMethodThatCanReturnNull.getReturnType(); 
    resultNotNull = replacementForNull.get(returnType); 
} 
+0

नहीं मिलेगाटर्न टाइप() वस्तु ऑब्जेक्ट? संकलन समय पर जेनेरिक मिटा दिए जाते हैं। – Pablo

+0

getReturnType() ऑब्जेक्ट लौटाएगा यदि रिटर्न टाइप ऑब्जेक्ट या जेनेरिक है जो ऑब्जेक्ट देता है। उपर्युक्त उदाहरणों में यह 'लांग' और' स्ट्रिंग ' –

+0

ठीक होगा, मैंने सवाल को गलत तरीके से पढ़ा, मैंने सोचा कि उनका मतलब था कि विधि "विधि" सामान्य थी। – Pablo

0

क्यों अपने T कुछ इंटरफेस को लागू करता है या कुछ आधार वर्ग का विस्तार नहीं कर सकता है? फिर आप T से कुछ स्थिर डिफ़ॉल्ट विधि को कॉल कर सकते हैं जो दिए गए वर्ग T के लिए डिफ़ॉल्ट मान वापस कर देता है। पेशेवरों? यह सिर्फ switch कोड को दाएं वर्ग में समाहित करेगा।

बेशक, बिना किसी इंटरफेस के, आपके सभी संभव T कक्षा में getDefaultValue() जैसी कुछ विधि हो सकती है।

+0

नहीं, मैं 'getDefaultValue()' विधि जोड़ने के लिए टी कक्षाओं को नहीं बदल सकता, न ही वे जो भी लौटते हैं उसे बदल सकते हैं। –

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