2012-02-28 28 views

उत्तर

11

हां।

List<Base> में विभिन्न चीजों का मिश्रण हो सकता है जो सभी Base से प्राप्त होते हैं। List<? extend Base> में समरूप वस्तुएं हैं (इस अर्थ में कि वे सभी को कुछ विशिष्ट, अज्ञात प्रकार से प्राप्त होना चाहिए जो बदले में Base से प्राप्त होता है)।

एक और तरीका रखें, List<? extends Base>List<T extends Base> के लिए बेस क्लास है। तो आप लेते हैं कि किसी भी विधि के लिए List<T extends Base> पास कर सकते हैं। List<Base> लेने वाली विधियों के लिए भी यह सच नहीं है।

+6

विशेष रूप से, आप 'सूची' के प्रकार को 'सूची' में नहीं जोड़ सकते हैं? बेस> 'बढ़ाता है। –

+3

@ लुइस वासरमैन: केवल इतना ही नहीं, लेकिन आप 'किसी भी वस्तु' ('null' को छोड़कर) को 'सूची <' में नहीं जोड़ सकते हैं? बेस> 'बढ़ाता है, क्योंकि आप नहीं जानते कि '?' किस प्रकार का प्रतिनिधित्व करता है। –

+0

@ लुइस वासरमैन: तो संक्षेप में, सूची किसी भी विधि को पारित किया जा सकता है जो सूची <लेता है? बेस>, सूची , सूची , या सूची सूची? तो कोई भी सूची का उपयोग क्यों करना चाहेंगे? मुझे यह भी पहेली है कि आप कर सकते हैं। (...) दोनों सूची और सूची को विस्तारित करता है, जहां '...' कुछ भी हो सकता है जो आधार से बेस या व्युत्पन्न (प्रत्यक्ष या परोक्ष रूप से) हो। – user113454

5

List<Base> list में Base या उसके किसी भी प्रकार के तत्व शामिल हो सकते हैं। JDK वर्गों के साथ कुछ उदाहरण:

List<Object> objects = new ArrayList<Object>(); 
objects.add(new Object()); // adding an Object instance 
objects.add("I am a String"); // a String instance is also an Object 
objects.add(Integer.valueOf(5)); // an Integer instance is also an Object 

लेकिन जब आप तत्वों को पुनः प्राप्त करने के लिए, आप केवल Object वर्ग के चर करने के लिए उन्हें प्रदान कर सकते हैं क्योंकि Object घोषित सूची के प्रकार पैरामीटर है।

Object first = objects.get(1); 
Object second = objects.get(2); 
Object third = objects.get(3); 

उनका वास्तविक क्रम कक्षाएं अभी भी Object, String और Integer कर रहे हैं, ताकि आप उन्हें उन प्रकार के लिए डाली और जैसे उन लोगों के साथ काम कर सकते हैं, लेकिन इस तरह डाले एक ClassCastException साथ कार्यावधि में विफल हो सकता है नहीं करता है, तो सही किया है और यह है आमतौर पर इस तरह के फैशन में सूचियों के साथ काम करने का अच्छा विचार नहीं है।

List<? extends Base> list एक घोषणा है कि वास्तव में घोषित चर के लिए नामित नहीं किया गया है क्योंकि के रूप में पहले से ही डैनियल Pryden की टिप्पणी में उल्लेख किया है - आप कर सकते हैं नहीं add() उस में किसी भी वस्तु, केवल null रों।

List<? extends String> list = new ArrayList<? extends String>(); 
list.add("a String")); // compile error! 

लेकिन आप इस तरह के एक सामान्य विधि पैरामीटर के लिए घिरे वाइल्डकार्ड अभिव्यक्ति का उपयोग कर सकते हैं।

boolean addAll(Collection<? extends E> c); 

यह आप इस तरह कुछ करने के लिए सक्षम बनाता है:: <? extend E> वाइल्डकार्ड के बिना

List<String> strings = Arrays.asList("a", "b"); 
List<Object> objects = new ArrayList<Object>(); 
objects.addAll(strings); 

इसे जोड़ने के लिए संभव नहीं होगा List से ही एक उदाहरण addAll() विधि जिनके हस्ताक्षर यह है है उन StringListObject एस में, क्योंकि जेनेरिक प्रकार (सरणी के विपरीत) कॉन्वर्स नहीं हैं। इसका मतलब है कि List<String>List<Object> का उप प्रकार नहीं है। लेकिन कोई भी String एक Object है, है ना? तो इसलिए बाध्य वाइल्डकार्ड के साथ विधि पैरामीटर घोषित करना आवश्यक है - List<String>List<? extends Object> का एक उप प्रकार है।

फिर से, मैं कहना है - घिरे वाइल्डकार्ड मुख्य रूप से सामान्य विधि मानकों, विधि वापसी प्रकार या चर घोषणाओं के लिए नहीं के लिए नामित कर रहे हैं।

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