2017-10-29 23 views
10

मैं कुछ गहराई में निचले बाउंड वाइल्डकार्ड के उपयोग को समझने की कोशिश कर रहा हूं। मैं एक सामान्य विधि copy लिखने की कोशिश कर रहा हूं जो एक List की सामग्री को दूसरे में कॉपी करता है। मैं इस विधि हस्ताक्षर के साथ आया:जावा जेनरिक पर कम बाध्य उपयोग:? सुपर टी

<T> void copy(List<T> dest, List<? extends T> src) 

मुझे लगता है कि यह हस्ताक्षर सभी परिदृश्यों को संबोधित करने के लिए व्यापक है। हालांकि, मैं देख रहा हूँ जावा संग्रह कक्षा में विधि हस्ताक्षर इस तरह है:

<T> void copy(List<? super T> dest, List<? extends T> src) 

मुझे समझ नहीं आता क्यों वे सिर्फ List<T> dest के बजाय List<? super T> dest का उपयोग करें। क्या उनके हस्ताक्षर के साथ कुछ अतिरिक्त लचीलापन है?

+0

आप अपने जेनेरिक खाने वाले HTML से बचने के लिए बैकटिक्स के साथ इनलाइन कोड को घेर सकते हैं। –

उत्तर

1

यहाँ एक उदाहरण है:

निम्नलिखित स्निपेट हस्ताक्षर <T> void copy(List<? super T> dest, List<? extends T> src) साथ संकलन गुजरता है लेकिन हस्ताक्षर <T> void copy(List<T> dest, List<? extends T> src) साथ काम नहीं करता:

YourClass obj = new YourClass(); 
List<HashMap<String,String>> lhm = new ArrayList<>(); 
List<Map<String,String>> lm = new ArrayList<>(); 
obj.<HashMap<String,String>>copy (lm,lhm); 
+0

उपरोक्त कोड स्निपेट दोनों हस्ताक्षरों के साथ संकलन पास करता है। बस ग्रहण में इसे चेक किया। – user496934

+0

@ उपयोगकर्ता496934 अजीब। मैंने ग्रहण पर भी इसका परीक्षण किया, और 'पैरामीटर विधि <हैश मैप <स्ट्रिंग, स्ट्रिंग >> प्रतिलिपि (सूची <हैश मैप <स्ट्रिंग, स्ट्रिंग >>, सूची >) को टाइप किया गया है टाइप करें आपका क्लासस नहीं है तर्कों के लिए लागू (सूची <मानचित्र <स्ट्रिंग, स्ट्रिंग >>, सूची <हैश मैप <स्ट्रिंग, स्ट्रिंग >>) ' – Eran

+1

@ user496934 क्या आपने कॉल 'obj। <हैश मैप <स्ट्रिंग, स्ट्रिंग >> कॉपी (एलएम, एलएमएम); 'या सिर्फ' obj.copy (एलएम, एलएमएम); '? – Eran

5

स्पष्ट प्रकार गवाहों के बिना कोई व्यावहारिक अंतर नहीं है।

ईरान द्वारा किए गए प्रकार के गवाह को निर्दिष्ट किए बिना, दो तरीकों के बीच लचीलापन में कोई अंतर नहीं है।

अनिवार्य रूप से, T से अधिक ? super T का उपयोग करते हैं, केवल एक शैलीगत अंतर नहीं है, लेकिन यह बेहतर अभ्यास है, के रूप में अच्छा कोड के सिद्धांतों के एक नंबर लगाने से देखा जा सकता है: और अधिक स्पष्ट रूप ? super T:

  • स्पष्ट मंशा दिखाता है कि किस प्रकार dest लेना चाहिए।
  • Modularity: आपको पर टाइप बाधाओं को देखने की आवश्यकता नहीं है, यह जानने के लिए कि किस प्रकार dest ले सकते हैं।
  • Producer Extends, Consumer Super (PECS): एक उत्पादक पैरामीटर (नीचे "नीचे") extends का उपयोग करना चाहिए जबकि उपभोक्ता पैरामीटर (नीचे "बाहर") super कीवर्ड का उपयोग करना चाहिए। दो कार्यों में से एक के रूप में उपलब्ध कराने के

    इस चर्चा के लिए, यह चर के बारे में सोचना उपयोगी है::

? super T का उपयोग करना भी Java tutorials द्वारा सिफारिश की है (वे भी एक copy समारोह का उपयोग करें)

एक "इन" वैरिएबल
एक "इन" चर कोड को डेटा प्रदान करता है। दो तर्कों के साथ copy विधि की कल्पना करें: copy(src, dest)src तर्क डेटा कॉपी करने के लिए प्रदान करता है, इसलिए यह "इन" पैरामीटर है।

एक "आउट" चर
एक "बाहर" चर अन्यत्र उपयोग के लिए डेटा रखती है। copy उदाहरण में, copy(src, dest), dest तर्क डेटा स्वीकार करता है, इसलिए यह "आउट" पैरामीटर है।

वाइल्डकार्ड का उपयोग करना है या किस प्रकार का वाइल्डकार्ड उचित है या नहीं, यह तय करते समय आप "इन" और "आउट" सिद्धांत का उपयोग कर सकते हैं। निम्न सूची का पालन करने के दिशा निर्देश प्रदान:

वाइल्डकार्ड दिशानिर्देश:

  • एक "में" चर extends कीवर्ड का उपयोग, एक ऊपरी घिरे वाइल्डकार्ड के साथ परिभाषित किया गया है।
  • super कीवर्ड का उपयोग करते हुए, "आउट" चर को निचले बाउंड वाइल्डकार्ड के साथ परिभाषित किया गया है।
+0

यह प्रश्न [यहां भी उत्तर दिया गया था] (https://stackoverflow.com/questions/34985220/differences-between-copylist-super-t-dest-list-extends-t-src-and-co)। मुझे लगता है कि उदाहरण उन सभी मामलों को दिखा रहा है जिनमें वे समकक्ष हैं, विशेष रूप से दृढ़ हैं। (बक्षीस के कारण डुप्ली के रूप में बंद नहीं किया जा सकता है।) – River

+0

@ रिवर: शायद यह एक फ्लैग ध्वज के साथ ध्वजांकित करना बेहतर होगा कि यह जवाब देने के बजाय यह एक डुप्ली है। – Makoto

+0

@ माकोटो ने बाद में डुप्लिकेट पाया – River

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