2015-09-16 8 views
6

निम्नलिखित कोड जावा में, मैंने एक सूची बनाई है nums। मैं घोषणा के दौरान एक और सूची असाइन कर सकते हैं। लेकिन null को छोड़कर नई वस्तुओं को जोड़ा नहीं जा सकता है। तो, क्या इसका मतलब है कि nums पढ़ा गया है? क्यों? क्या उस सूची में नए आइटम जोड़ना संभव है?"? पेरेंट क्लास बढ़ाता है" केवल पढ़ने के लिए बनाता है?

List<Integer> ints = new ArrayList<Integer>(); 
ints.add(1); 
ints.add(2); 

List<? extends Number> nums = ints; 
nums.add(3.14); //Generates error 
nums.addAll(ints); //Generates error 

nums.add(null);  //works 
System.out.println(nums.get(0)); //works 

मैं इस link से गुजर चुका हूं। मुझे सटीक कारण नहीं मिल रहा है।

+0

मुझे नहीं पता, nums.add ((संख्या) नया डबल (3.14)) ध्यान दें; परिणाम में त्रुटि: प्रकार सूची में कैप्चर (कैप्चर # 1-ऑफ? विस्तार संख्या) <कैप्चर # 1-के? संख्या बढ़ाता है> तर्कों के लिए लागू नहीं है (संख्या) –

+1

यह प्रश्न देखें: http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs – Natix

+0

यह एक बहुत ही आम गलतफहमी है; लेकिन अधिकांश मामलों में गर्भधारण काम करता है :) – ZhongYu

उत्तर

5

Is it possible to add new items in that list?

नहीं ... क्योंकि वह कोड नहीं जानता कि यह वास्तव में "सूची" क्या है। कल्पना कीजिए अगर आप किए जा सकेंगे:

List<String> strings = new ArrayList<>(); 
List<? extends Object> objects = strings; // This is fine 
objects.add(new Object()); // Fortunately this *isn't* valid... 
System.out.println(strings.get(0).length()); // Or what would this do? 

मूल रूप से, जब आप ? extends T की तरह एक वाइल्डकार्ड का उपयोग आप केवल मूल्यों बाहर एपीआई के माध्यम से प्राप्त कर सकते हैं ... और जब आप ? super T की तरह एक वाइल्डकार्ड का उपयोग, आप केवल रख सकते हैं में एपीआई के माध्यम से मूल्य - क्योंकि यह सुरक्षित है।

+0

तो, क्या हम कह सकते हैं कि सूची केवल पढ़ी जाएगी? –

+4

@PipipKharbuja: नहीं, वास्तव में नहीं। सूची स्वयं केवल पढ़ने के लिए नहीं है - आप अभी भी 'ints' के माध्यम से इसमें जोड़ सकते हैं, या इसे 'nums' के माध्यम से हटा सकते हैं। टाइप सुरक्षा की वजह से आप * num * में * जोड़ नहीं सकते हैं। –

-1

जेनिक्स केवल संकलन समय है।

तो कंपाइलर तय करेगा कि वास्तविक प्रकार क्या है जिसका हम उपयोग करने जा रहे हैं।

List<? extends Number> 

इसका मतलब है कि हम निश्चित नहीं हैं कि वस्तु का वास्तविक प्रकार क्या है।

तो कंपाइलर यह सुनिश्चित नहीं करता कि सूची में वास्तविक प्रकार क्या है।

2

नहीं, यह केवल पढ़ने के लिए नहीं है ... भले ही यह आमतौर पर इरादा है।

List<? extends Number> ऑब्जेक्ट को देखते हुए, कंपाइलर converts इसका प्रकार List<X> है जहां एक्स संख्या का अज्ञात उप प्रकार है। इसलिए, ऑब्जेक्ट में add(X) विधि है। हम विधि को X तर्क के साथ कॉल कर सकते हैं ... उदाहरण के लिए, null

और get() रिटर्न के बाद से X, हम भी add() एक मूल्य के साथ get() से कह सकते हैं .... सीधे लागू list.add(list.get(i)) काम नहीं करेगा, भले ही यह समझ में आता है। हमें थोड़ा helper की आवश्यकता होगी।

क्लासिक उदाहरण Collections.reverse(List<? extends Object> list) है। वाइल्डकार्ड के बावजूद यह विधि list को संशोधित करेगी।

आप किसी भी सूची में, clear() जैसे उत्परिवर्तनीय विधियों को भी कॉल कर सकते हैं।


कहा जा रहा है, वाइल्डकार्ड उपयोग साइट variance के लिए वास्तव में मुख्य रूप से है, और सबसे अधिक बार, यह एक प्रकार पैरामीटर बाहर या में के लिए है कि क्या की एपीआई डिजाइनर से इरादा बता देते हैं। उदाहरण के लिए, List<? super/extends Foo> घोषित करके, एपीआई व्यक्त करता है कि यह पर टी इंजेक्ट करने का इरादा रखता है, या , सूची में से टी प्राप्त करें।

यह एक गलतफहमी है कि वाइल्डकार्ड केवल पढ़ने/लिखने के लिए बनाता है। लेकिन यह गलत धारणा ज्यादातर उपयोग मामलों में काम करती है। से अधिक लोगों को यह गलत धारणा है, और अधिक यह एक सम्मेलन हो जाता है ...

मेरे लेख वाइल्डकार्ड पर देखते हैं - http://bayou.io/draft/Capturing_Wildcards.html

0

यह मदद करता है जब आप बात के कुछ प्रकार है कि Number फैली की एक List रूप List<? extends Number> nums के बारे में सोच , लेकिन आप सुनिश्चित नहीं कर सकते कि क्या। इस प्रकार, nums के साथ आप जो भी करते हैं, वह ऐसी चीज करने में सक्षम होना चाहिए।

null जोड़ना काम करता है क्योंकि null बिल्कुल कुछ भी में डाला जा सकता है। जो कुछ भी आप जोड़ने का प्रयास करते हैं, वह असफल हो जाएगा, क्योंकि संकलक 100% निश्चित नहीं हो सकता है कि जो चीज आप जोड़ रहे हैं वह सूची उस चीज को बढ़ाती है जो सूची बनाई गई है।

List<? extends Number> numsList<Number> nums पर करें, क्योंकि आप अभी भी Number तक फैले कुछ भी डाल सकते हैं।

? का मतलब "कुछ भी नहीं" है, यह "कुछ विशिष्ट लेकिन अज्ञात" अर्थ के करीब है।

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