2013-06-04 6 views
6

List और List<?> के बीच क्या अंतर है? मुझे पता है कि मैं List<?> पर कोई तत्व नहीं जोड़ सकता। क्योंकि यह समय त्रुटि संकलन का कारण बनता है,सूची और सूची <?> जावा में

List<String> myList = new ArrayList<String>(); 
processList(myList); 
processListGeneric(myList); 

public static void processList(List myList) { 
Iterator it = myList.iterator(); 
while(it.hasNext()) 
    System.out.println(it.next()); 
} 

public static void processListGeneric(List<?> myList) { 
    Iterator<?> it = myList.iterator(); 
    while(it.hasNext()) 
     System.out.println(it.next()); 
} 

दो तरीकों में से नाम समान नहीं हो सकती: मैं एक कोड है। तो क्या इन दो दृष्टिकोणों में कोई अंतर है?

+2

यह संकलित नहीं करता है क्योंकि दोनों विधियों का एक ही हस्ताक्षर होगा, क्योंकि जेनेरिक (<>) केवल कंपाइलर द्वारा संकलन समय पर प्रकार के विरुद्ध जांचने के लिए उपयोग किया जाता है। – Sebastien

+1

आप इसमें शून्य जोड़ सकते हैं। तो यह न कहें कि आप इसमें कुछ भी नहीं जोड़ सकते :) –

+0

दूसरी विधि का उपयोग करके 'java.awt.List' के साथ, मुझे नहीं लगता कि आपकी कक्षा संकलित होगी ...;) – Mikaveli

उत्तर

1

अंतर यह है कि आप List<?> पर कुछ भी नहीं जोड़ सकते हैं, क्योंकि यह किसी अज्ञात प्रकार की सूची है।

उदाहरण के लिए, यदि आप ऐसा करने से रोका जाता है:

List<Integer> listOfInt = new ArrayList<Integer>(); 
List<?> list = listOfInt; 
list.add("hello?"); // Compile-time error 

आप सूची आइटम के प्रकार के चेक नहीं किया गया के बाद से कुछ भी आधार प्रकार List को आप चाहते हैं जोड़ सकते हैं।

6

दोनों एक ही करते हैं, लेकिन दूसरे मामले में कंपाइलर को सूचित किया जाता है कि आप वास्तव में किसी भी प्रकार की सीमा के साथ एक सूची चाहते हैं और कोई चेतावनी नहीं उठाती है। यदि आप जावा 5 के साथ काम कर रहे हैं या बाद में आपको दूसरे दृष्टिकोण का उपयोग करने के लिए प्रोत्साहित किया जाता है।

+3

' सूची 'नहीं * 'सूची ' के समान। चूंकि ओपी ने बताया, आप 'सूची ' में जोड़ नहीं सकते हैं, जबकि यह निश्चित रूप से 'सूची ' में जोड़ने के लिए पूरी तरह से संभव है। इसके अलावा, यदि कोई विधि 'सूची ' को तर्क के रूप में लेती है, तो यह पास करने के लिए कानूनी है, उदाहरण के लिए, 'सूची '। एक विधि जो 'सूची ' लेती है, 'सूची ' स्वीकार नहीं करेगी। – sepp2k

+0

@ sepp2k हटाया विवादास्पद हिस्सा। –

+2

आप अभी भी दावा कर रहे हैं कि "दोनों एक ही काम करते हैं"। विधि का दूसरा संस्करण उन तर्कों को स्वीकार करेगा जो पहले नहीं हैं। तो विधि के दो संस्करण समान नहीं हैं। – sepp2k

0

दूसरी विधि जेनेरिक का उपयोग करती है (जावा 5 में पेश की गई)।

List<? extends Object> myList 

तो आप कह सकते हैं कि (वाइल्डकार्ड वाक्य रचना के बिना) पहले पद्धति का उपयोग करके अधिक लचीला है, आप के रूप में ':

एक महत्वपूर्ण अंतर <?> एक ही प्रकार, नहीं इस तरह किसी भी वस्तु का प्रतिनिधित्व करता है डी अपनी सूची में कोई वस्तु जोड़ने में सक्षम हो। हालांकि, आपको एक (कंपाइलर) चेतावनी मिलेगी कि आप घोषणा को पैरामीटरकृत किया जाना चाहिए।

<?> का उपयोग करके असंबद्ध वाइल्डकार्ड वाक्यविन्यास चेतावनी से बच जाएगा, लेकिन आप कंपाइलर को बता रहे हैं कि यह वास्तव में टाइप सुरक्षा को लागू करने के लिए जेनरिक का उपयोग करने के बजाय किसी भी प्रकार की सूची हो सकता है। आपको अपने आवेदन प्रकार को सुरक्षित बनाने में सहायता करने के लिए जेनिक्स का उपयोग करने के लिए दृढ़ता से प्रोत्साहित किया जाता है।

, उदाहरण के लिए, आप जानते हैं कि सूची ही कभी स्ट्रिंग वस्तुओं को शामिल करना चाहिए, यह इस प्रकार की घोषणा:

List<String> myList 

तो फिर तुम instanceof ऑपरेटर के उपयोग के अनावश्यक कास्टिंग बच सकेंगे, आदि

यहाँ, जावा में जेनरिक पर संक्षिप्त ट्यूटोरियल है आपकी जानकारी के लिए:

http://javarevisited.blogspot.co.uk/2011/09/generics-java-example-tutorial.html

0

उनमें से दोनों समान व्यवहार करते हैं। Parametrized नोटेशन का उपयोग आप जावा 5 और ऊपर में किसी भी चेतावनी से परहेज कर रहे हैं। आपके पास एक ही जावा फ़ाइल में सिंटैक्स दोनों नहीं हो सकते हैं क्योंकि टाइप एरर संकलित इकाई के कारण समान वर्ग फ़ाइल में एक ही हस्ताक्षर के साथ दो विधियां हैं और इस प्रकार भाषा नियमों का उल्लंघन होता है। निम्नलिखित है कि आप कंपाइलर से क्या प्राप्त करेंगे:

विधि प्रक्रिया सूची (सूची) में एक ही मिटा प्रक्रिया है सूची (सूची) प्रकार में एक और विधि के रूप में ...

1

List<?> (उच्चारण "अज्ञात संग्रह") एक संग्रह है जिसका तत्व प्रकार कुछ भी मेल खाता है। इसे स्पष्ट कारणों से वाइल्डकार्ड प्रकार कहा जाता है। जब से हम क्या myListNew के लिए खड़ा के तत्व प्रकार, हम नहीं वस्तुओं इसे करने के लिए जोड़ सकते हैं पता नहीं है निम्नलिखित कोड

List<String> myList = new ArrayList<String>(); 
myList.add("John"); 
String name = myList.get(0); 
System.out.println(name); //print John 
List<?> myListNew = myList; 
myListNew.add("Sam");//Compile time error 
String nameNew = myListNew.get(0);//Compile time error 
Object newName = myListNew.get(0); 
System.out.println(newName);//Prints John 

का संदर्भ लें। ऐड() विधि प्रकार ई, संग्रह के तत्व प्रकार के तर्क लेती है। जब वास्तविक प्रकार पैरामीटर होता है, तो यह किसी अज्ञात प्रकार के लिए खड़ा होता है। हमारे द्वारा जोड़े जाने वाले किसी भी पैरामीटर को इस अज्ञात प्रकार का उप-प्रकार होना चाहिए। चूंकि हम नहीं जानते कि यह किस प्रकार का है, हम कुछ भी पास नहीं कर सकते हैं। एकमात्र अपवाद शून्य है, जो हर प्रकार का सदस्य है।

दूसरी ओर, List<?> दिए गए, हम get() को कॉल कर सकते हैं और परिणाम का उपयोग कर सकते हैं। परिणाम प्रकार एक अज्ञात प्रकार है, लेकिन हम हमेशा जानते हैं कि यह एक वस्तु है। इसलिए ऑब्जेक्ट प्रकार के चर के लिए() को प्राप्त करने के परिणाम को सुरक्षित करना या इसे पैरामीटर के रूप में पास करना सुरक्षित है जहां ऑब्जेक्ट की अपेक्षा की जाती है।

0

बस टाइप पैरामीटर के बिना List लिखना बहिष्कृत है, लेकिन अन्यथा List<Object> लिखने जैसा ही है। तो सवाल बन जाता है "List<Object> और List<?> और मुझे किस का उपयोग करना चाहिए?" के बीच क्या अंतर है?

आप पहले से ही जानते हैं, आप नहीं (null के अलावा और कुछ) एक List<?> को जोड़ सकते हैं, इसलिए यदि आप एक सूची में जोड़ने की जरूरत है, तो आप एक List<Object> (या एक अधिक विशिष्ट प्रकार जहां लागू का उपयोग करना चाहिए निश्चित रूप से,)। दूसरी तरफ, एक विधि जो List<Object> लेती है, केवल List<Object> एस स्वीकार करती है और कोई भी सूचियां नहीं जिसमें Object का सबक्लास होता है। यही है, यह List<String> स्वीकार नहीं करेगा। यदि विधि List<?> लेती है, तो यह किसी भी प्रकार की सूची स्वीकार करती है। इसलिए यदि आपको सूची में जोड़ने की आवश्यकता नहीं है, तो आपको List<?> का उपयोग करना चाहिए क्योंकि यह अधिक सामान्य है।

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