गेट-पुट सिद्धांत की व्याख्या


83

मैंने ओ'रिली किताब पढ़ी है, उसमें मुझे इस गेट-पुट सिद्धांत का पता चला ।

  • extendsजब आप केवल किसी संरचना से मान प्राप्त करते हैं तो वाइल्डकार्ड का उपयोग करें ।
  • superवाइल्डकार्ड का उपयोग करें जब आप केवल एक संरचना में मान डालते हैं।
  • और जब आप दोनों को एक संरचना में लाना और लगाना चाहते हैं, तो वाइल्डकार्ड का उपयोग न करें।

अपवाद हैं:

  • आप extendsमूल्य को छोड़कर वाइल्डकार्ड के साथ घोषित प्रकार में कुछ भी नहीं डाल सकते हैं null, जो हर संदर्भ प्रकार से संबंधित है।

  • आप प्रकार के superमूल्य को छोड़कर वाइल्डकार्ड के साथ घोषित प्रकार से कुछ भी नहीं प्राप्त कर सकते हैं Object, जो कि प्रत्येक संदर्भ प्रकार का एक सुपर प्रकार है।

क्या कोई मुझे इस नियम का गहराई से पता लगाने में मदद कर सकता है? यदि संभव हो, तो कृपया उन्हें पदानुक्रमित तरीके से रखें।


4
+1: किसी को मूल रूप से स्पष्टीकरण मांगते हुए देखना हमेशा अच्छा होता है
हर कोई

2
@ हर कोई, मुझे लगता है कि आप मूलभूत अर्थों के बजाय मौलिक अर्थों में मौलिक हैं?
रिच सेलर

जवाबों:


167

केले के एक गुच्छा पर विचार करें। यह इस प्रकार है Collection<? extends Fruit>कि यह एक विशेष प्रकार के फलों का एक संग्रह है - लेकिन आप नहीं जानते (उस घोषणा से) यह किस प्रकार का फल है। आप इससे एक आइटम प्राप्त कर सकते हैं और जानते हैं कि यह निश्चित रूप से एक फल होगा, लेकिन आप इसे नहीं जोड़ सकते हैं - आप केले के एक गुच्छा में सेब जोड़ने की कोशिश कर रहे होंगे, जो निश्चित रूप से गलत होगा। आप इसे जोड़ सकते हैं null, क्योंकि यह किसी भी प्रकार के फलों के लिए एक वैध मूल्य होगा ।

अब एक फ्रूटब्लो पर विचार करें। यह एक है Collection<? super Banana>, इसमें कुछ प्रकार का संग्रह है "से अधिक" Banana(उदाहरण के लिए, Collection<Fruit>या Collection<TropicalFruit>)। आप इसमें केला जरूर मिला सकते हैं, लेकिन अगर आप कटोरे में से एक ऐसी चीज लाते हैं जो आपको नहीं पता कि आपको क्या मिलेगा - यह अच्छी तरह से केला नहीं हो सकता है। आप सभी जानते हैं कि यह एक वैध (संभवतः null) Objectसंदर्भ होगा।

(सामान्य तौर पर, जावा जेनरिक प्रश्नों के लिए, जावा जेनरिक एफएक्यू एक उत्कृष्ट संसाधन है, जिसमें लगभग कुछ भी जेनरिक-संबंधित का उत्तर होता है, जिसे आप इसे फेंकने की संभावना रखते हैं।)


लेकिन संग्रह से एक फल प्राप्त करते समय <? फलों का विस्तार करता है>, आपको केला नहीं फल मिल सकता है। इसी तरह, फलों को डालते समय, यू किसी भी चीज को जोड़ सकता है जो केले के फलों से संबंधित नहीं हो सकता है
JavaResp

6
जावा आपको Collection<? extends Fruit>उस कारण के लिए अशक्त के अलावा कुछ भी जोड़ने से रोक देगा , और आपको उन कारणों के लिए एक आइटम लाने के परिणाम को स्पष्ट रूप से डालना होगा।
जॉन स्कीट

@JonSkeet यह एक बेवकूफी भरा सवाल हो सकता है, लेकिन किन मामलों में यह उपयोगी है कि दोनों को जोड़ने () और पाने () के तरीकों तक "पहुंच" नहीं है? मेरा मतलब है, किसी सूची से बाहर निकलने के लिए (), आपको इसे पहले जोड़ना होगा, है ना? और इसके अलावा, यदि आप इसे बाद में नहीं प्राप्त कर सकते हैं तो आप इसे क्यों जोड़ेंगे?
टिम्मोस १os

7
@Timmos: सिर्फ इसलिए कि किसी चीज को एक मूल्य जोड़ने में सक्षम होना है, इसका मतलब यह नहीं है कि सभी कोड को सक्षम करने की आवश्यकता है। उदाहरण के लिए, व्यक्ति के नामों की सूची प्रदर्शित करने के लिए, मुझे सिर्फ Collection<? extends Person>(या शायद सिर्फ एक Iterable<? extends Person>, लेकिन ...) की आवश्यकता हो सकती है । उस संग्रह को बनाने वाला कोड अच्छी तरह से इसकी आवश्यकता हो सकती है Collection<Employee>, लेकिन उपभोग कोड नहीं करता है।
जॉन स्कीट

5
@Timmos: आपको इस मामले में "इसके" द्वारा बिल्कुल वही कहना होगा जो आप चाहते हैं ... लेकिन हां, जावा जेनरिक के नियम प्रकार की सुरक्षा प्रदान करने के लिए बनाए गए हैं।
जॉन स्कीट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.