2011-10-26 8 views
27

किसी को भी पता है क्यों जावा 1.6 इस व्यवहार है:क्यों सूची <String> .toArray() वस्तु ऑब्जेक्ट [] और स्ट्रिंग नहीं []? इस के आसपास कैसे काम करें?

List<String> list = ArrayList<String>(); 
String[] arr = (String[]) list.toArray(); 

और मैं एक ClassCastException मिलता है, क्योंकि यह वस्तु [] और रिटर्न String [] नहीं।

मैंने सोचा List<T>.toArray() टी [] - नहीं लौटा देना चाहिए? क्या किसी के पास कोई जवाब है कि भाषा में यह असुविधा क्यों मौजूद है? और इसके आसपास कैसे काम करना है? मैं वस्तुओं के माध्यम से लूपिंग के बिना List<String> से एक स्ट्रिंग [] कैसे प्राप्त करूं?

+2

Jave में परिवर्तित नहीं किया जा सकता है नहीं करता है ' टी वास्तव में 'टी []' की अवधारणा नहीं है। – Gabe

+0

[जावा: (स्ट्रिंग \ [\]) की संभावित डुप्लिकेट List.toArray() ClassCastException देता है] (http://stackoverflow.com/questions/5690351/java-stringlist-toarray-gives-classcastexception) –

उत्तर

20

आपको एक सरणी में पास करने की आवश्यकता है, इसलिए इसके रनटाइम प्रकार को toArray द्वारा संकेत के रूप में उपयोग किया जा सकता है। इसके बजाय toArray(new String[0]) आज़माएं। आप एक पूर्व आकार के सरणी में भी पास कर सकते हैं।

समझने के लिए, पर विचार किस प्रकार विलोपन बनाने के लिए

new T[4] 

काम करने के लिए होगा। यदि जावा की अनुमति दी है कि, सबसे अच्छा यह पद विलोपन कर सकता है

new Object[4] 

अधिकांश toArray कार्यान्वयन java.lang.reflect.Array का प्रयोग कर एक प्रकार संकेत एक Class के रूप में पारित दिया सही प्रकार का उत्पादन सरणी के निर्माण के लिए।

+0

धन्यवाद माइक, मैंने इस विधि को टी [] toArray (टी [] arg0) नहीं देखा - यह मुझे जो चाहिए वह देता है। – justadreamer

+9

या 'toArray (नई स्ट्रिंग [list.size()]) का उपयोग करें, यदि आप आकार 0 सर –

+0

@ratchetfreak के आवंटन से बचना चाहते हैं, धन्यवाद। Presizing के बारे में बात करने के लिए संपादित किया। –

12

क्योंकि शुरुआत से ही जावा जावा में हैं, जबकि जेनेरिक केवल जावा 5 में पेश किए गए थे और जेनरिक्स अस्तित्व से पहले जावा 1.2 में List.toArray() विधि पेश की गई थी, और इसलिए इसे Object[] वापस करने के लिए निर्दिष्ट किया गया था। लौटने के लिए अब मौजूदा कोड के बहुत सारे List.toArray() की उम्मीद है, इसलिए इसे अब बदला नहीं जा सकता है।

इसके अलावा, जेनेरिक रनटाइम पर मिटा दिए जाते हैं, इसलिए ArrayList उचित प्रकार की सरणी भी नहीं बना सका अगर वह चाहता था।

इसके लिए छेड़छाड़ List.toArray(T[]) विधि है, जो आपको सही प्रकार की एक सरणी लौटाएगी, बशर्ते आप इसे सही प्रकार की सरणी दें ताकि यह जान सके कि किस प्रकार का उपयोग करना है।

+1

"और इसलिए यह ऑब्जेक्ट [] को वापस करने के लिए निर्दिष्ट किया गया था। मौजूदा कोड के बहुत सारे अब List.toArray() ऑब्जेक्ट को वापस करने के लिए उम्मीद करते हैं [], इसलिए इसे अब बदला नहीं जा सकता है।" बकवास। जावा संग्रह विधियों 'जेनरिक्स के लिए रिटर्न प्रकार बदल दिए गए थे। यह पूरी तरह से अप्रासंगिक है। वास्तविक कारण यह है कि रनटाइम पर विभिन्न प्रकार के सरणी अलग-अलग होते हैं और इस प्रकार यह उचित प्रकार की सरणी को संभवतः वापस नहीं कर सकता है। जेनेरिक से पहले और बाद में यह सच है। – newacct

+0

डैनियल, गंभीरता से? इस प्रश्न पर कितनी बार पूछा गया है? दस लाख? और आप मुझे डुप्लिकेट प्रश्न का उत्तर देने के लिए व्याख्यान दे रहे थे? – irreputable

+0

@irreputable: मैंने कल जवाब दिया जब मैंने तुरंत एक सही डुप्लिकेट नहीं देखा (और न ही याद रखें)। एक त्वरित खोज आज चालू हुई [यह एक] (http://stackoverflow.com/questions/6173495/why-does-javas-collectione-toarray-return-an-object-rather-than-an-e) जो मुझे लगता है काफी करीब है। यदि आप आश्वस्त हैं कि एक प्रश्न एक डुप्लिकेट है, तो बुरा विश्वास संभालने के बजाय, क्यों न सिर्फ खुद को बंद करने के लिए वोट दें? आपके पास पर्याप्त प्रतिनिधि है –

3

यह समझने के लिए कि ऐसा क्यों होता है, बस Collection.toArray() के लिए जावाडोक पर एक नज़र डालें और फिर Collection.toArray(T[] a) विधि देखें। यह भी ध्यान रखें कि जावा में जेनेरिक रनटाइम पर मिटा दिए जाते हैं।

1

कारणों दो हैं:

  1. विधि पहले जेनेरिक्स और वे पश्च संगतता को तोड़ने के बिना हस्ताक्षर नहीं बदल सके।

  2. किसी भी मामले में, List के रूप में एक Class<T> बिना निर्माण किया है वहाँ लागू करने के लिए कोई रास्ता नहीं प्रकार T की एक सरणी के निर्माण के लिए है।

     List<String> list = new ArrayList<>(); 
         list.add("Sputnik"); 
         list.add("Explorer"); 
    
         //String[] str = list.toArray(); 
    

    यह स्वाभाविक है एक फेंक: असंगत प्रकार:

+0

आप हस्ताक्षर को क्या बदलेंगे? – newacct

+0

@newacct से टी [] निश्चित रूप से। डाउनवॉटर कृपया समझाओ। – EJP

+0

आपका मतलब वापसी प्रकार टी [] है? यदि आप इसका उपयोग करने का प्रयास करते हैं तो आपको क्लासकास्ट अपवाद प्राप्त होगा, क्योंकि जब भी आप कोई विधि हस्ताक्षर बदलते हैं तो विधि अभी भी ऑब्जेक्ट [] – newacct

1

तरीके का उपयोग करने के लिए किया जाएगा वस्तु [] String [] त्रुटि

 Instead use: 

     String[] str = list.toArray(new String[0]); 
     or 
     String[] str = list.toArray(new String[list.size()]); 
संबंधित मुद्दे