2010-04-19 22 views
36

मैं एक विधि है कि एक प्रकार परम स्वीकार कर सकते हैं (या जो भी विधि से प्रकार पता लगा सकते हैं) और इस प्रकार के कोई मान तो मैं वापसी कास्ट करने के लिए की जरूरत नहीं है लिखने के लिए करना चाहते हैं प्रकार।जावा सामान्य वापसी प्रकार

यहाँ एक विधि है:

public Object doIt(Object param){ 
    if(param instanceof String){ 
     return "string"; 
    }else if(param instanceof Integer){ 
     return 1; 
    }else{ 
     return null; 
    } 
} 

जब मैं इस विधि कहते हैं, और उस में एक स्ट्रिंग पारित, भले ही मैं जानता हूँ कि वापसी प्रकार एक स्ट्रिंग मैं वापसी वस्तु कास्ट करने के लिए है हो जाएगा। यह int param के समान है।

मैं एक प्रकार परम इस प्रकार स्वीकार करते हैं, और वापस जाने के लिए इस विधि कैसे लिख होगा?

+2

एक महत्वपूर्ण सवाल यह है कि आप हमेशा स्ट्रिंग और int का उपयोग करेंगे या नहीं। यदि ऐसा है, तो आप एक सामान्य विधि नहीं चाहते हैं। आप दो विधियों को चाहते हैं, जो एक int स्वीकार करता है और एक int देता है, और दूसरा जो एक स्ट्रिंग स्वीकार करता है और देता है। –

उत्तर

67

आपको लगता है कि सामान आप इस तरह से एक सामान्य विधि का उपयोग कर सकते हैं संभाल करने के लिए एक विशिष्ट अंतरफलक के लिए नहीं करना चाहते हैं:

public <T> T mymethod(T type) 
{ 
    return type; 
} 

मन में है कि इस प्रकार संकलक उस विधि के बारे में कुछ भी नहीं जानता जिसे आप उस विधि के अंदर उपयोग करने की योजना बना रहे हैं, इसलिए आपको बाध्य प्रकार का उपयोग करना चाहिए, उदाहरण के लिए:

public <T extends YourType> T mymethod(T type) 
{ 
    // now you can use YourType methods 
    return type; 
} 

लेकिन क्या आप वाकई एक सामान्य विधि की जरूरत है कि हो सकता है, कि इसका मतलब है कि doIt के कार्यान्वयन सभी प्रकार आप के साथ इसका इस्तेमाल करने की योजना बना रहे हैं के लिए एक ही हो जाएगा। अन्यथा यदि हर कार्यान्वयन अलग बस तरीकों को ओवरलोड है, यह बाध्यकारी तरीके से कार्य करेंगे के बाद से वापसी प्रकार गतिशील के लिए नहीं किया जाता है:

public String my(String s) 
{ 
    return s; 
} 

public int my(int s) 
{ 
    return s; 
} 

int i = my(23); 
String s = my("lol"); 
10

इस के साथ प्रारंभ:

public interface Command<T> 
{ 
    T execute(T parameter); 
} 
0

मैं नहीं उपयोग instanceof करने के लिए आप से आग्रह करता हूं जाएगा, फिर भी इस कोड क्या करता है आप चाहते हैं:

public class Main 
{ 
    public static void main(String[] args) 
    { 
     final Main main; 
     final String strVal; 
     final Integer intVal; 
     final Float floatVal; 

     main  = new Main(); 
     strVal = main.doIt("Hello"); 
     intVal = main.doIt(5); 
     floatVal = main.doIt(5.0f); 

     System.out.println(strVal); 
     System.out.println(intVal); 
     System.out.println(floatVal); 
    } 

    public <T> T doIt(final T thing) 
    { 
     T t; 

     if(thing instanceof String) 
     { 
      t = (T)"String"; 
     } 
     else if (thing instanceof Integer) 
     { 
      t = (T)Integer.valueOf(1); 
     } 
     else 
     { 
      t = null; 
     } 

     return (t); 
    } 
} 
+0

अपने उदाहरण से आप बस अधिक भार के बजाय एक सामान्य विधि का उपयोग कर इस्तेमाल कर सकते हैं, वापसी प्रकार के बाद से गतिशील बंधन के लिए इस्तेमाल नहीं कर रहे हैं .. निश्चित रूप से – Jack

+1

, मैं सिर्फ जवाब यह है कि कोड संभव के रूप में तैनात करने के लिए के रूप में करीब था देने के लिए कोशिश कर रहा था। मुझे लगता है कि कोड मेरा उत्तर में तैनात एक भयानक विचार है और मैं इसका इस्तेमाल नहीं होगा, यह कर क्या वांछित है :-) – TofuBeer

8

संक्षिप्त उत्तर नहीं है। जैसे ही instanceof शामिल हो जाता है, जेनेरिक आमतौर पर गलत जवाब होते हैं। इसके बजाय अधिभारित विधियों का उपयोग करें:

public String doIt(String param){ 
    return "string"; 
} 

public Integer doIt(Integer param){ 
    return 1; 
} 

public Object doIt(Object param){ 
    return null; 
} 
+2

6 साल बाद के बावजूद ... कहा कि, अगर घोषित प्रकार 'Object', इस जीत है वैरिएबल ओवरलोडिंग वैरिएबल के घोषित प्रकार के आधार पर संकलन समय पर किया जाता है। – Powerlord

+0

अर्थात अगर आप 'वस्तु var =" बेकन "है,' तब के बावजूद है कि एक 'स्ट्रिंग',' छदाम (वस्तु परम) किया जा रहा है 'कहा जाता। – Powerlord

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