2015-05-18 4 views
7

मैं Listक्या ऐरेलिस्ट <Integer> स्ट्रिंग जोड़ने की अनुमति देता है?

List list = new ArrayList<Integer>(); 
    ListIterator<Integer> litr = null; 
    list.add("A"); 

    list.add("1"); 

    list.add(5); 

    litr = list.listIterator(); 
    while(litr.hasNext()){ 
     System.out.println("UIterating " + litr.next()); 
    } 

मैं यह उम्मीद एक ClassCastException फेंकने के लिए निम्न कोड बताया तत्वों का एक सरल उदाहरण भर में आया था, बल्कि यह सांत्वना

A 
1 
5 

जो अजीब लग रहा है को यह लिखा था । जब मैंने कोशिश की:

List<Integer> list = new ArrayList<Integer>(); 

मुझे संकलन समय त्रुटि मिली।

मैं अगर किसी को समझा सकता है कि कैसे String वस्तुओं ArrayList

+4

http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens – CupawnTae

+4

http://stackoverflow.com/questions/2770321/what-is-a-raw -टाइप-एंड-क्यों-चाहिए-हम-उपयोग- – Reimeus

+1

मैं इसे एक वाक्य में जोड़ सकता हूं: "जावा में, जेनेरिक केवल संकलन समय पर ही किए जाते हैं।" ऐसा कहकर, जावा इस कारण से कच्चे प्रकारों का उपयोग करने के बारे में आपको चेतावनी देता है। – Powerlord

उत्तर

4

से जुड़ जाते हैं तो आपको एक untyped सूची के लिए नए ArrayList सौंपा आभारी होंगे। जेनेरिक प्रकार प्रतिबंध एक untyped सूची पर लागू नहीं होते हैं, यह आपको जो कुछ भी आप चाहते हैं उसे डाल देगा। कंपाइलर ट्रैक नहीं रखता है कि आपकी अनियमित सूची उस चीज़ को संदर्भित करती है जिसे सामान्य प्रकार के साथ घोषित किया गया था।

किसी भी मामले में यह क्लासकास्ट अपवाद उत्पन्न नहीं करेगा, जेनेरिक केवल संकलन को प्रभावित करेगा। क्रम

मामले में जहां आप सूची चर पर प्रकार डाल पर:

List<Integer> list = new ArrayList<Integer>(); 

पसंद किया जाता है, यह एक संकलक आपको बता आप संग्रह में गलत प्रकार डाल रहे हैं त्रुटि उत्पन्न करना चाहिए।

वहाँ कैसे विरासत, गैर सामान्य कोड और सामान्य कोड this article में interoperate का वर्णन दिया गया:

उचित जेनेरिक कोड में, संग्रह हमेशा एक प्रकार पैरामीटर के साथ किया जाएगा। जब एक सामान्य प्रकार जैसे संग्रह को प्रकार पैरामीटर के बिना प्रयोग किया जाता है, तो इसे कच्चे प्रकार कहा जाता है।

अधिकांश लोगों की पहली प्रवृत्ति यह है कि संग्रह वास्तव में Collection<Object> का मतलब है। हालांकि, जैसा कि हमने पहले देखा था, को उस स्थान पर पास करना सुरक्षित नहीं है जहां Collection<Object> आवश्यक है। यह कहना अधिक सटीक है कि प्रकार संग्रह कुछ अज्ञात प्रकार के संग्रह को दर्शाता है, जैसे कि Collection<?>

लेकिन प्रतीक्षा करें, यह सही नहीं हो सकता है! getParts() पर कॉल पर विचार करें, जो संग्रह देता है। इसके बाद इसे के लिए असाइन किया जाता है, जो Collection<Part> है। यदि कॉल का परिणाम Collection<?> है, तो असाइनमेंट एक त्रुटि होगी।

असल में, असाइनमेंट कानूनी है, लेकिन यह एक अनचेक चेतावनी उत्पन्न करता है। चेतावनी की आवश्यकता है, क्योंकि तथ्य यह है कि संकलक इसकी शुद्धता की गारंटी नहीं दे सकता है। हमारे पास getAssembly() में विरासत कोड की जांच करने का कोई तरीका नहीं है यह सुनिश्चित करने के लिए कि वास्तव में संग्रह वापस किया जा रहा है, पार्ट्स का संग्रह है। कोड में इस्तेमाल किया जाने वाला प्रकार संग्रह है, और कोई कानूनी रूप से इस तरह के संग्रह में सभी प्रकार की वस्तुओं को सम्मिलित कर सकता है।

तो, क्या यह कोई त्रुटि नहीं होनी चाहिए? सैद्धांतिक रूप से बोलते हुए, हाँ; लेकिन व्यावहारिक रूप से बोलते हुए, यदि सामान्य कोड विरासत कोड को कॉल करने जा रहा है, तो इसकी अनुमति होनी चाहिए। यह आपके लिए है, प्रोग्रामर, स्वयं को संतुष्ट करने के लिए कि इस मामले में, असाइनमेंट सुरक्षित है क्योंकि getAssembly() का अनुबंध कहता है कि यह पार्ट्स का संग्रह देता है, भले ही प्रकार हस्ताक्षर यह नहीं दिखाता है।

+0

बस एक एफवाईआई: आपको उद्धरण में कोड के चारों ओर कोड ब्लॉक रखना चाहिए। अन्यथा, आप नहीं देख सकते कि संग्रह में से एक संग्रह 'संग्रह ' – Powerlord

+0

@ पावरलोर्ड: दाएं, धन्यवाद –

+0

@NathanHughes आपके उत्तर के लिए धन्यवाद। Untyped सूची और कच्चे संग्रह के बारे में एक विचार मिला –

1

इसका कारण यह है कि कैसे जेनरिक जावा में लागू किया जाता है के लिए संभव है - type erasure का उपयोग कर, और क्योंकि जावा जावा (1.4 और ऊपर) के पुराने संस्करणों के साथ पिछली संगतता के लिए raw types का समर्थन करता है।

जेनेरिक केवल आपके स्रोत कोड में मौजूद हैं। कंपाइलर संकलन-समय पर प्रकारों की जांच करने के लिए उनका उपयोग करता है, लेकिन फिर जेनरिक को फेंकता है। रनटाइम पर, List<Integer> ऑब्जेक्ट्स की केवल List है, और यह नहीं पता कि यह एक सूची है जिसमें केवल Integer ऑब्जेक्ट्स होनी चाहिए।

जावा पुराने संस्करणों के साथ पिछड़े संगतता के लिए List<Integer> के बजाय List जैसे कच्चे प्रकारों के उपयोग का समर्थन करता है। जब आप कच्चे प्रकार का उपयोग करते हैं, जैसा कि आप उपरोक्त कोड में कर रहे हैं, तो आपको एक कंपाइलर चेतावनी मिलती है। आपको नए कोड में कच्चे प्रकार का उपयोग नहीं करना चाहिए - केवल तब भी उनका उपयोग करें जब आपको पुराने कोड से निपटने की आवश्यकता हो जिसे आप नहीं बदल सकते हैं।

कच्चे प्रकार और प्रकार के मिरर का संयोजन आपको सूचियों में वस्तुओं के प्रकारों को रखने की अनुमति देता है जिन्हें आपको वहां नहीं डालना चाहिए।

क्योंकि List रनटाइम पर इस प्रकार के तत्वों के बारे में कुछ भी नहीं पता है, यह किसी भी चीज की जांच नहीं करता है, इसलिए आपको ClassCastException नहीं मिलेगा।

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