2012-09-19 18 views
7

विस्तारित कक्षा वस्तुओं के संग्रह बनाना पहली पंक्ति क्यों काम करती है, लेकिन दूसरा नहीं है?जावा जेनरिक: थ्रोबल

Collection<Class<? extends Throwable>> exs = 
    new ArrayList<Class<? extends Throwable>>() {{ add(MyOwnException.class); }}; 
Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class); 

उत्तर

3

जेनिक्स बहुत मुश्किल हैं।

इस मामले में Arrays.asListList<Class<MyOwnException>> लौटाएगा, जो List<Class<? extends Throwable>> से समान नहीं है।

उनका व्यवहार अलग के बाद से प्रकार List<Class<? extends Throwable>> आप वस्तुओं है कि फेंकने योग्य विस्तार लेकिन List<Class<MyOwnException>> ही प्रकार MyOwnException की वस्तुओं को स्वीकार जोड़ने के लिए अनुमति होगी होगा।

+1

कि सच नहीं है कि वे "बिल्कुल वैसा ही" होना जरूरी: 'सूची एक्स = नए ArrayList ();' संकलित करता है, जैसा कि सूची <करता है? संख्या> x = new ArrayList (); ' – Bohemian

+0

आप सही हैं, बोहेमियन, मैंने बस दूसरे भाग को सही किया, जो सत्य नहीं था। जल्दी जवाब देने के लिए बुरा घंटे। धन्यवाद! – enTropy

0

दूसरे उदाहरण काम करने के लिए थे, तो इसे इस तरह कोड के लिए अनुमति होगी:

Collection<Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class); 
exs.add(IOException.class); 

समस्या देखते हैं? Arrays.asList()List<Class<MyOwnException>> वापस करेगा, और फिर आप उसमें Class<IOException> डालने का प्रयास करेंगे। यह स्पष्ट रूप से एक प्रकार का मेल नहीं है।

1

पहली पंक्ति से काम करता है क्योंकि (ArrayList का) assignement की दाईं ओर के तत्व के प्रकार Class<? extends Throwable>Class<? extends Throwable> वस्तु के किसी भी प्रकार जोड़ने के लिए, अपने MyOwnException सहित अनुमति देता है। आप यह भी पहली पंक्ति Collection एक Exception.class या एक NullPointerException.class, आदि

को जोड़ सकता है लेकिन दूसरी पंक्ति बहुत सख्त है: यदि आप एक Collection<Class<? extends Throwable>> एक Class<Exception>, एक Class<NullPointerException>, आदि शामिल हो सकता है कि और आप में डाल करना चाहते हैं एक Collection<Class<MyOwnException>> है कि Class<Exception> लिए अनुमति देता है नहीं, जगह आदि

6

कारण यह एक त्रुटि है कि जावा गलत प्रकार का निष्कर्ष निकालते है, लेकिन आप, कास्टिंग बिना यह संकलन, कर सकते हैं कॉल में प्रकार को निर्दिष्ट करके टाइप की गई विधि Arrays.asList():

Collection<Class<? extends Throwable>> exs 
    = Arrays.<Class<? extends Throwable>>asList(Exception.class); // compiles 

प्रकार को निर्दिष्ट के बिना, जावा संग्रह का तत्व प्रकार infers Class<Exception>, जो है Collection<Class<? extends Throwable>> को आबंटित नहीं किया जाना है।

जेनरिक के साथ याद रखें कि यदि B फैली A, List<B> करता नहीं विस्तार List<A>

+0

+1, लेकिन मेरे पास एक प्रश्न है। स्थानीय चर को 'कक्षा <के रूप में परिभाषित क्यों नहीं किया जाता है?थ्रोबल> क्लैज '' Arrays.asList (clazz) 'में चाल करता है? – Raffaele

+1

@Raffaele क्योंकि इस प्रकार को 'aslist' के पैरामीटर से 'क्लास ' के रूप में अनुमानित किया गया है, लेकिन आपको इसे अलग होने की आवश्यकता है – Bohemian

+0

असल में ग्रहण कंपाइलर कहता है 'सूची <कक्षा <कैप्चर # 1-का? थ्रोबल >> सूची <वर्ग <तक फैलाता है? थ्रोबल फैलाता है >> ', इसमें' कक्षा 'का उल्लेख नहीं है, लेकिन मैं * कैप्चर # 1 * भाग की व्याख्या नहीं कर सकता ... – Raffaele

1

Arrays.asList(MyOwnException.class) टाइप List<Class<MyOwnException>> टाइप करने का अनुमान है, जो List<Class<? extends Throwable>> के साथ संगत नहीं है क्योंकि टाइप पैरामीटर अलग हैं।

आप पहले के स्तर पर एक वाइल्डकार्ड डालें, तो वह काम करना चाहिए:

Collection<? extends Class<? extends Throwable>> exs = Arrays.asList(MyOwnException.class); 
संबंधित मुद्दे