जावा जेनरिक के टाइप पैरामीटर में प्रश्न चिह्न का क्या मतलब है?


216

यह कुछ छोटे उदाहरणों से लिया गया कोड का एक छोटा सा टुकड़ा है जो स्टैनफोर्ड पार्सर के साथ है। मैं लगभग 4 वर्षों से जावा में विकास कर रहा हूं, लेकिन कभी भी इस बारे में बहुत मजबूत समझ नहीं थी कि इस कोड की शैली को क्या संकेत दिया जाना चाहिए।

List<? extends HasWord> wordList = toke.tokenize();

मैं कोड के विवरण के बारे में चिंतित नहीं हूं। मैं इस बारे में उलझन में हूं कि अंग्रेजी में सामान्य अभिव्यक्ति क्या है।

क्या कोई मुझे ये समझा सकता है?


जवाबों:


226
? extends HasWord

का अर्थ है "एक वर्ग / इंटरफ़ेस जो विस्तारित होता है HasWord।" दूसरे शब्दों में, HasWordस्वयं या इसके किसी भी बच्चे ... मूल रूप से कुछ भी जो instanceof HasWordप्लस के साथ काम करेगा null

अधिक तकनीकी शब्दों में, ? extends HasWordएक बाउंडेड वाइल्डकार्ड है, जो प्रभावी जावा 3 संस्करण के 31 आइटम में शामिल है , जो पेज 139 पर शुरू होता है। 2 डी संस्करण से एक ही अध्याय पीडीएफ के रूप में ऑनलाइन उपलब्ध है ; बाउंडेड वाइल्डकार्ड पर हिस्सा आइटम 28 पेज 134 पर शुरू हो रहा है।

अपडेट: पीडीएफ लिंक अपडेट किया गया था क्योंकि ओरेकल ने इसे कुछ समय पहले हटा दिया था। अब यह क्वीन मैरी यूनिवर्सिटी ऑफ लंदन के स्कूल ऑफ इलेक्ट्रॉनिक इंजीनियरिंग एंड कंप्यूटर साइंस द्वारा आयोजित कॉपी की ओर इशारा करता है।

अपडेट 2: आओ हम थोड़ा और विस्तार करें कि आप वाइल्डकार्ड का उपयोग क्यों करना चाहते हैं।

यदि आप एक ऐसी विधि घोषित करते हैं जिसके हस्ताक्षर से आप पास होने की उम्मीद करते हैं List<HasWord>, तो केवल एक चीज जिसे आप पास कर सकते हैं वह है ए List<HasWord>

हालाँकि, अगर कहा जाता है कि हस्ताक्षर थे List<? extends HasWord>तो आप List<ChildOfHasWord>इसके बजाय पास कर सकते थे ।

ध्यान दें कि List<? extends HasWord>और के बीच एक सूक्ष्म अंतर है List<? super HasWord>। जैसा कि यहोशू बलोच ने कहा: PECS = निर्माता-विस्तार, उपभोक्ता-सुपर।

इसका मतलब यह है कि यदि आप एक संग्रह में गुजर रहे हैं जो आपकी विधि से डेटा को खींचता है (यानी संग्रह आपकी उपयोग करने की विधि के लिए तत्वों का उत्पादन कर रहा है), तो आपको उपयोग करना चाहिए extends। यदि आप किसी ऐसे संग्रह से गुजर रहे हैं जिसमें आपकी विधि डेटा जोड़ती है (अर्थात संग्रह आपके द्वारा बनाए गए तत्वों का उपभोग कर रहा है), तो इसका उपयोग करना चाहिए super

यह भ्रामक लग सकता है। हालाँकि, आप इसे List's sortकमांड में देख सकते हैं (जो कि कलेक्शंस के दो-arg वर्जन का शॉर्टकट है। Sort)। इसके बजाय Comparator<T>, यह वास्तव में एक लेता है Comparator<? super T>। इस स्थिति में, तुलनित्र Listसूची को पुन: क्रम में करने के लिए तत्वों का उपभोग कर रहा है।


17
"कुछ भी है कि उदाहरण के साथ काम करेगा" - शून्य मान। याद रखें कि अशक्त मान किसी भी उदाहरण जांच के लिए गलत हैं।
ईयाल श्नाइडर

12
इंटरफेस मत भूलना। ? एक वर्ग का प्रतिनिधित्व करने के लिए नहीं है!
मार्क पीटर्स

9
List<HasWord>यह वही है जो आप वर्णन करते हैं: एक सूची जिसमें कोई भी वस्तु होती xहै जिसके लिए x instanceof HasWordवह सही है, और null। इसके लिए आपको वाइल्डकार्ड की आवश्यकता नहीं है। वाइल्डकार्ड का अर्थ है कि यह वास्तव में एक अन्य प्रकार की सूची हो सकती है, वह भी, जब तक कि यह प्रकार उप-प्रकार है HasWord। (देर से टिप्पणी के लिए क्षमा करें।)
पाओलो एबरमन

1
PDF लिंक काम नहीं करता है, लेकिन यह मेरे लिए उपयोगी था: docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
user1338062

यह अजीब है, मुझे पिछले साल एक संदेश कभी नहीं मिला जब @ user1338062 पोस्ट किया गया था और पता नहीं था कि पीडीएफ लिंक काम नहीं कर रहा था। अब तय हो गया। मैंने स्वयं पुस्तक का लिंक भी जोड़ा।
पॉवरलॉर्ड

65

एक प्रश्न चिह्न 'किसी भी प्रकार' के लिए एक हस्ताक्षरकर्ता है। ?अकेले का मतलब है

किसी भी प्रकार का विस्तार Object(सहित Object)

जबकि ऊपर आपके उदाहरण का मतलब है

किसी भी प्रकार का विस्तार या कार्यान्वयन HasWord( HasWordयदि HasWordएक गैर-सार वर्ग है)


2
तो क्या public Set<Class<?>> getClasses()मतलब है? इससे क्या फर्क पड़ता है Set<Class>? मैं देख रहा हूं javax.ws.rs.core.Application
तिजोरी

14

List<? extends HasWord>किसी भी ठोस वर्गों को स्वीकार करता है जो हसवर्द का विस्तार करता है। यदि आपके पास निम्न वर्ग हैं ...

public class A extends HasWord { .. }
public class B extends HasWord { .. }
public class C { .. }
public class D extends SomeOtherWord { .. }

... wordListदोनों की सूची में केवल As या Bs या दोनों का मिश्रण हो सकता है क्योंकि दोनों वर्ग समान माता-पिता का विस्तार करते हैं या null(जो इंस्टॉफ़ चेक को विफल करता है HasWorld)।


8
केवल ठोस ही नहीं, सार उपवर्ग भी।
ब्लोपारोड

2
न केवल ठोस और सार उपवर्ग, बल्कि उप-इंटरफेस भी List<? extends Collection<String>> list = new ArrayList<List<String>>();:।
मार्क पीटर्स

2
आपको इसके लिए वाइल्डकार्ड की जरूरत नहीं है, वास्तव में: List<HasWord>इसके लिए भी। यहाँ पर बात यह है कि इस चर में a List<A>या List<B>साथ ही a भी हो सकता है List<HasWord>
पाओलो एबरमन

12

शायद एक वंचित "वास्तविक दुनिया" उदाहरण से मदद मिलेगी।

मेरे काम के स्थान पर हमारे पास अलग-अलग स्वादों में आने वाले डिब्बे हैं। सभी डिब्बे में खारिश होती है, लेकिन कुछ डिब्बे विशेषज्ञ होते हैं और सभी प्रकार की बकवास नहीं करते हैं। तो हमारे पास है Bin<CupRubbish>और Bin<RecylcableRubbish>। इस प्रकार की प्रणाली को यह सुनिश्चित करने की आवश्यकता है कि मैं अपने HalfEatenSandwichRubbishको इन प्रकारों में नहीं डाल सकता , लेकिन यह एक सामान्य बकवास बिन में जा सकता है Bin<Rubbish>। अगर मैं उस बारे में बात करना चाहता था Bin, Rubbishजो विशेष हो सकता है तो मैं असंगत बकवास में नहीं डाल सकता, तो वह होगा Bin<? extends Rubbish>

(नोट: ? extendsकेवल पढ़ने के लिए मतलब नहीं है। उदाहरण के लिए, मैं उचित सावधानियों के साथ अज्ञात विशेषता के बिन से बकवास का एक टुकड़ा निकाल सकता हूं और बाद में इसे वापस एक अलग स्थान पर रख सकता हूं।)

यकीन नहीं होता कि इससे कितनी मदद मिलती है। पॉलीमॉर्फिज़्म की उपस्थिति में पॉइंटर-टू-पॉइंटर पूरी तरह से स्पष्ट नहीं है।


5

अंग्रेजी में:

यह Listकुछ प्रकार का है जो कक्षा को विस्तारित करता है HasWord, जिसमें शामिल हैHasWord

?जेनेरिक में सामान्य रूप से किसी भी वर्ग का मतलब है। और extends SomeClassनिर्दिष्ट करता है कि उस वस्तु का विस्तार होना चाहिए SomeClass(या वह वर्ग हो)।


1
दरअसल, क्लास के बजाय टाइप करें । यह सिर्फ इंटरफेस के लिए काम करता है।
पाओलो एबरमन

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.