List<? extends Base> list
List<Base> list
क्या दो घोषणाओं के बीच कोई अंतर है?सूची <? बेस> वीएस सूची <Base>
धन्यवाद,
List<? extends Base> list
List<Base> list
क्या दो घोषणाओं के बीच कोई अंतर है?सूची <? बेस> वीएस सूची <Base>
धन्यवाद,
हां।
List<Base>
में विभिन्न चीजों का मिश्रण हो सकता है जो सभी Base
से प्राप्त होते हैं। List<? extend Base>
में समरूप वस्तुएं हैं (इस अर्थ में कि वे सभी को कुछ विशिष्ट, अज्ञात प्रकार से प्राप्त होना चाहिए जो बदले में Base
से प्राप्त होता है)।
एक और तरीका रखें, List<? extends Base>
List<T extends Base>
के लिए बेस क्लास है। तो आप लेते हैं कि किसी भी विधि के लिए List<T extends Base>
पास कर सकते हैं। List<Base>
लेने वाली विधियों के लिए भी यह सच नहीं है।
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()
विधि जिनके हस्ताक्षर यह है है उन String
List
Object
एस में, क्योंकि जेनेरिक प्रकार (सरणी के विपरीत) कॉन्वर्स नहीं हैं। इसका मतलब है कि List<String>
List<Object>
का उप प्रकार नहीं है। लेकिन कोई भी String
एक Object
है, है ना? तो इसलिए बाध्य वाइल्डकार्ड के साथ विधि पैरामीटर घोषित करना आवश्यक है - List<String>
List<? extends Object>
का एक उप प्रकार है।
फिर से, मैं कहना है - घिरे वाइल्डकार्ड मुख्य रूप से सामान्य विधि मानकों, विधि वापसी प्रकार या चर घोषणाओं के लिए नहीं के लिए नामित कर रहे हैं।
विशेष रूप से, आप 'सूची' के प्रकार को 'सूची' में नहीं जोड़ सकते हैं? बेस> 'बढ़ाता है। –
@ लुइस वासरमैन: केवल इतना ही नहीं, लेकिन आप 'किसी भी वस्तु' ('null' को छोड़कर) को 'सूची <' में नहीं जोड़ सकते हैं? बेस> 'बढ़ाता है, क्योंकि आप नहीं जानते कि '?' किस प्रकार का प्रतिनिधित्व करता है। –
@ लुइस वासरमैन: तो संक्षेप में, सूची आधार बढ़ाता है> किसी भी विधि को पारित किया जा सकता है जो सूची <लेता है? बेस>, सूची , सूची , या सूची सूची? तो कोई भी सूची का उपयोग क्यों करना चाहेंगे? मुझे यह भी पहेली है कि आप कर सकते हैं। (...) दोनों सूची बेस> और सूची को विस्तारित करता है, जहां '...' कुछ भी हो सकता है जो आधार से बेस या व्युत्पन्न (प्रत्यक्ष या परोक्ष रूप से) हो। –
user113454