जावा जेनरिक (वाइल्डकार्ड्स)


109

मेरे पास जावा में सामान्य वाइल्डकार्ड के बारे में कुछ प्रश्न हैं:

  1. बीच क्या अंतर है List<? extends T>और List<? super T>?

  2. एक बाउंडेड वाइल्डकार्ड क्या है और एक अनबाउंड वाइल्डकार्ड क्या है?


इस मामले में कि टेड गाओ का उत्तर हटा दिया गया है (क्योंकि यह केवल लिंक था), यहाँ वह ब्लॉग पोस्ट है जिससे यह जुड़ा हुआ है।
रोहिणी

जवाबों:


123

आपके पहले प्रश्न में, <? extends T>और <? super T>बंधे हुए जंगली जानवरों के उदाहरण हैं। एक अनबाउंड वाइल्डकार्ड जैसा दिखता है <?>, और मूल रूप से इसका मतलब है <? extends Object>। इसका सीधा मतलब है कि सामान्य कोई भी प्रकार हो सकता है। एक बाउंडेड वाइल्डकार्ड ( <? extends T>या <? super T>) यह कहकर प्रकार पर प्रतिबंध लगाता है कि उसे या तो एक विशिष्ट प्रकार का विस्तार करना है ( <? extends T>जिसे ऊपरी सीमा के रूप में जाना जाता है), या उसे एक विशिष्ट प्रकार का पूर्वज होना चाहिए ( <? super T>इसे एक निम्न सीमा के रूप में जाना जाता है) ।

जावा ट्यूटोरियल्स में वाइल्डकार्ड्स और वाइल्डकार्ड्स के साथ मोर फन में जेनेरिकों की कुछ बहुत अच्छी व्याख्याएँ हैं ।


बस इसे सही पाने के लिए, अगर A <B और B <C तब: <A का विस्तार C> गलत है?
पाब्लो फर्नांडीज

यदि ए <बी द्वारा, आपका मतलब है कि ए का विस्तार बी है, तो ए सी का विस्तार करता है। आप वाइल्डकार्ड सिंटैक्स में इसका उपयोग नहीं करेंगे, तो आप कहेंगे <? अपनी पसंद को A या B. तक सीमित करने के लिए C> का विस्तार करता है
छिपकली

और उस मामले में अगर मैं कहूं < सुपर सी> क्या अंतर होगा?
पाब्लो फर्नांडीज

3
बस जावा जेनरिक पर एक और संदर्भ की सिफारिश करना चाहते थे: angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
Zach Scrivena

3
@ पाब्लो: <? super C>का मतलब होगा कि आपका Cप्रकार पदानुक्रम में ऊपर की किसी चीज़ तक सीमित है । (अत्यंत देर से उत्तर के लिए क्षमा करें। मुझे लगता है कि हमारे पास 2 साल पहले टिप्पणी सूचनाएं नहीं थीं?)
छिपकली

49

यदि आपके पास एक श्रेणी पदानुक्रम A है, B, A का उपवर्ग है, और C और D दोनों नीचे B का उपवर्ग हैं

class A {}
class B extends A {}
class C extends B {}
class D extends B {}

फिर

List<? extends A> la;
la = new ArrayList<B>();
la = new ArrayList<C>();
la = new ArrayList<D>();

List<? super B> lb;
lb = new ArrayList<A>(); //fine
lb = new ArrayList<C>(); //will not compile

public void someMethod(List<? extends B> lb) {
    B b = lb.get(0); // is fine
    lb.add(new C()); //will not compile as we do not know the type of the list, only that it is bounded above by B
}

public void otherMethod(List<? super B> lb) {
    B b = lb.get(0); // will not compile as we do not know whether the list is of type B, it may be a List<A> and only contain instances of A
    lb.add(new B()); // is fine, as we know that it will be a super type of A 
}

एक बाउंडेड वाइल्डकार्ड ऐसा है ? extends Bजहां बी कुछ प्रकार है। यही है, प्रकार अज्ञात है लेकिन उस पर एक "बाध्य" रखा जा सकता है। इस मामले में, यह कुछ वर्ग द्वारा बाध्य है, जो बी का एक उपवर्ग है।


मुझे लगता List<? super B>है के रूप में सूची का वर्णन है कि वर्ग बी के मूल वर्ग है स्वीकार करता है ? यही कारण है कि सी और डी हम्म संकलन नहीं करेंगे?
Volkan ग्यूवेन

38

जोश बलोच भी जब उपयोग करने के लिए की एक अच्छी व्याख्या है superऔर extendsइस में वीडियो बात कब गूगल जहां उन्होंने उल्लेख निर्माता extendsउपभोक्ताsuper स्मरक।

प्रस्तुति स्लाइड से:

मान लीजिए कि आप बल्क मेथड जोड़ना चाहते हैं Stack<E>

void pushAll(Collection<? extends E> src);

- src एक E निर्माता है

void popAll(Collection<? super E> dst);

- dst एक E उपभोक्ता है


मैंने बलोच की पुस्तक पढ़ी है, लेकिन मैं अभी भी इस विशेष मामले में विस्तार और सुपर के बीच अंतर नहीं देख सकता हूं।
पाब्लो फर्नांडीज

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

2
बेड - इसे पूरा करने और अकेले खड़े होने के लिए इस उत्तर में उदाहरण क्यों शामिल नहीं है। लिंक पंचांग हैं।
जेम्स स्कैच

3

ऐसे समय हो सकते हैं जब आप उन प्रकारों को प्रतिबंधित करना चाहते हैं, जिन्हें एक प्रकार के पैरामीटर को पारित करने की अनुमति है। उदाहरण के लिए, संख्याओं पर काम करने वाला एक तरीका केवल संख्या या उसके उपवर्गों के उदाहरणों को स्वीकार करना चाहता है। यह वह है जो बंधे हुए प्रकार के मापदंडों के लिए है।

Collection<? extends MyObject> 

इसका मतलब है कि यह सभी ऑब्जेक्ट को स्वीकार कर सकता है जिनके पास IS- MyObject के साथ एक संबंध है (अर्थात कोई भी वस्तु जो MyObject का एक प्रकार है या हम MyObject के किसी भी उपवर्ग के किसी भी ऑब्जेक्ट को कह सकते हैं) या MyObject वर्ग का ऑब्जेक्ट।

उदाहरण के लिए:

class MyObject {}

class YourObject extends MyObject{}

class OurObject extends MyObject{}

फिर,

Collection<? extends MyObject> myObject; 

केवल MyObject या MyObject के बच्चों को स्वीकार करेगा (अर्थात किसी प्रकार की वस्तु OurObject या YourObject या MyObject, लेकिन MyObject के सुपरक्लास की कोई वस्तु नहीं)।


1

सामान्य रूप में,

यदि किसी संरचना में एक प्रकार के रूप वाले तत्व होते हैं ? extends E, तो हम तत्वों को संरचना से बाहर निकाल सकते हैं, लेकिन हम तत्वों को संरचना में नहीं डाल सकते हैं

List<Integer> ints = new ArrayList<Integer>();
ints.add(1);
ints.add(2);
List<? extends Number> nums = ints;
nums.add(3.14); // compile-time error
assert ints.toString().equals("[1, 2, 3.14]"); 

तत्वों को संरचना में रखने के लिए हमें एक और प्रकार के वाइल्डकार्ड की आवश्यकता होती है Wildcards with super, जिसे कहा जाता है ,

 List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
    List<Integer> ints = Arrays.asList(5, 6);
    Collections.copy(objs, ints);
    assert objs.toString().equals("[5, 6, four]");

    public static <T> void copy(List<? super T> dst, List<? extends T> src) {
          for (int i = 0; i < src.size(); i++) {
                dst.set(i, src.get(i));
         }
    }

1

जेनेरिक वाइल्डकार्ड ऐसे तरीकों को बनाने के लिए बनाए जाते हैं जो संग्रह को अधिक पुन: प्रयोज्य पर संचालित करते हैं।

उदाहरण के लिए, यदि किसी विधि में एक पैरामीटर है List<A>, तो हम केवल List<A>इस विधि को दे सकते हैं । यह कुछ परिस्थितियों के तहत इस पद्धति के मज़े के लिए एक बेकार है this

  1. यदि यह विधि केवल वस्तुओं को पढ़ती है List<A>, तो हमें देने की अनुमति दी जानी चाहिएList<A-sub> इस पद्धति । (क्योंकि-उप IS ए है)
  2. यदि यह विधि केवल वस्तुओं को सम्मिलित करती है List<A>, तो हमें List<A-super>इस पद्धति को देने की अनुमति दी जानी चाहिए । (क्योंकि एक ए-सुपर है)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.