2012-07-19 9 views
7

मैं इस तरह एक विधि कॉल करने के लिए कोशिश कर रहा हूँ में जेनरिक प्रकार के साथ वर्ग पाने के लिए,कैसे जावा

public class GenericsTest<T> { 

    public static <T> Map<String, T> createMap(Class<? extends Map<String, T>> clazz) { 
     return null; 
    } 

    public static void main(String[] argv) { 
     Map<String, Integer> result = createMap(TreeMap.class); 
    } 
} 

लेकिन मैं इस त्रुटि हो रही है,

<T>createMap(java.lang.Class<? extends java.util.Map<java.lang.String,T>>) in test.GenericsTest<T> cannot be applied to (java.lang.Class<java.util.TreeMap>) 

इस समस्या को ठीक करने के लिए?

+0

आप टाइप एरर के कारण नहीं कर सकते हैं। विशेष रूप से, विधि हस्ताक्षर समझ में नहीं आता है क्योंकि आप 'टी' प्राप्त करने की कोशिश कर रहे हैं, भले ही आप 'टी'' के रूप में मान पैरामीटर के साथ 'क्लास' के लिए 'कक्षा' में ले रहे हों। आप वस्तु के मौजूदा उदाहरण के बिना नेस्टेड प्रकार कभी भी प्राप्त नहीं कर पाएंगे। (आप '(नया हैश मैप <स्ट्रिंग, इंटीजर>()) में प्राप्त कर सकते हैं। GetClass()', लेकिन आप अभी भी उस विधि से 'इंटीजर' वापस नहीं प्राप्त कर पाएंगे)। – pickypg

+0

createMap() एक लाइब्रेरी से है जिसका हम उपयोग करते हैं। उस विधि को कॉल करने का एक तरीका होना चाहिए। –

+0

मैं लौटे ऑब्जेक्ट की वैधता पर सवाल करता हूं। माना जाता है कि यह 'मान' के लिए 'कक्षा' में पारित होने पर मान पैरामीटर, 'टी' का एक उदाहरण लौटा रहा है, और विधि का नाम' createMap' है। इसमें से कोई भी कोई समझ नहीं आता है। – pickypg

उत्तर

3
Map<String, Integer> instance = new TreeMap<String, Integer>(); 

@SuppressWarnings("unchecked") 
Map<String, Integer> map = 
    createMap((Class<? extends Map<String, Integer>>)instance.getClass()); 

map.put("x", 1); 

System.out.println("THIS IS x: " + map.get("x")); 

यह उचित रूप से बाहर 1. प्रिंट होगा विधि के क्रियान्वयन की संभावना सबसे अधिक

try 
{ 
    return clazz.newInstance(); 
} 
catch (Exception e) 
{ 
    throw new RuntimeException(e); 
} 

उन्हें, प्रकार के लिए आप से पूछना करने के लिए T उनके एपीआई का एक बेहतर कार्यान्वयन किया जाएगा है, और के लिए उन्हें सभी विवरणों के लिए पूछने के बजाय उनके चयन के Map वापस देने के लिए। अन्यथा, जब तक कि वे किसी भी डेटा के साथ Map में भरने नहीं कर रहे हैं, तब तक आप सामान्य प्रकार तर्क के साथ एक Map खुद तो तरह का दृष्टांत कर सकते हैं:

public static <T> Map<String, T> getMap() 
{ 
    return new TreeMap<String, T>(); 
} 

फिर आप उपयोग कर सकते हैं कि एक चेतावनी के बिना:

// note the lack of type arguments, which are inferred 
Map<String, Integer> instance = getMap(); 

// alternatively, you could do it more explicitly: 
// Map<String, Integer> instance = ClassName.<Integer>getMap(); 

वहाँ वास्तव में कोई कारण नहीं है उन्हें आप अपने Map को छोड़कर की Class प्रकार के लिए पूछने के लिए के लिए तुम वापस कार्यान्वयन के लिए एक सटीक मिलान (उदाहरण के लिए, यदि आप एक HashMap में रहना है, तो आप वापस एक HashMap मिल जाएगा देने के लिए है, और अगर आपमें चिपके रहते हैं, तो आप एक TreeMap वापस प्राप्त करेंगे)। हालांकि, मुझे संदेह है कि TreeMap किसी भी Comparator को खो देगा, जिसका निर्माण किया गया था, और चूंकि यह TreeMap का एक अपरिवर्तनीय (final) फ़ील्ड है, तो आप इसे ठीक नहीं कर सकते; इसका मतलब है कि Map उस मामले में समान नहीं है, और न ही यह वही होना चाहिए जो आप चाहते हैं।

यदि वे डेटा के साथ Map भर रहे हैं, तो यह भी कम समझ में आता है। आप भरने के लिए Map के उदाहरण में हमेशा पास हो सकते हैं, या उन्हें Map वापस कर सकते हैं जिन्हें आप आसानी से लपेट सकते हैं (उदा।, new TreeMap<String, Integer>(instance);), और उन्हें पता होना चाहिए कि Map डेटा के लिए सबसे अधिक उपयोगिता प्रदान करता है।

+0

यह अनचेक चेतावनी के साथ चलता है। चेतावनी के बिना इस विधि को कॉल करने का एक तरीका होना चाहिए। जेनेरिक का उपयोग करने का यह पूरा उद्देश्य है। –

+0

आप इस उद्देश्य के बारे में सही हैं, लेकिन जावा में टाइप एरर की वजह से जेनेरिक सीमित है, जो इस समस्या का कारण बन रहा है; कंपाइलर को आपके लिए करने में सक्षम किए बिना आप क्या कर सकते हैं इसकी सीमाएं हैं। यह शायद जावा की मेरी सबसे पसंदीदा विशेषता है क्योंकि उनके लिए इसे ठीक करना या प्रतिस्थापित करना सबसे कठिन होगा। .NET में अधिक बहुमुखी जेनेरिक सिस्टम है क्योंकि वे रनटाइम पर भुला नहीं जाते हैं। संकलन के बाद, वह नक्शा एक्सेस '(इंटीजर) map.get ("x") बन जाएगा क्योंकि लौटा हुआ प्रकार वास्तव में' ऑब्जेक्ट 'है। – pickypg