दिलचस्प पोस्ट
डिबग मोड के लिए एंड्रॉइड स्टूडियो में एसएचए -1 फिंगरप्रिंट सर्टिफिकेट कैसे प्राप्त करें? SYSTEM_ALERT_WINDOW – एंड्रॉइड 6.0 और लक्ष्य पर स्वचालित रूप से इस अनुमति को कैसे प्राप्त करें SDKVersion 23 आपको ORM का उपयोग क्यों करना चाहिए? सरणी पैरामीटर का आकार मुख्य के समान क्यों नहीं है? सी प्रीप्रोसेसर, मैक्रो का परिणाम स्ट्रिंग करें जावा का उपयोग करते हुए पीडीएफ फाइलों को कैसे पढ़ें? एंड्रॉइड 6.0 मार्शमॉलो एसडी कार्ड पर लिख नहीं सकते आईओएस: यूआरएल से छवि डाउनलोड करें और उपकरण में सहेजें Excel VBA में एक पंक्ति हटाएं बाएं संरेखण के रूप में UIButton का शीर्षक कैसे सेट करें? एक पायथन स्क्रिप्ट चलते समय vcvarsall.bat नहीं मिल सकता एक टुकड़ा में Google Maps API V2 जोड़ें मैक ओएस एक्स पर पायथन 3 के लिए पीईपी कैसे स्थापित करें? संपूर्ण फ़ाइल को खोलने के बिना, ज़िप फ़ाइल से डेटा कैसे पढ़ा जाए SqlDateTime.MinValue! = दिनांकटाइम.मिनवैल्यू, क्यों?

सामान्य तरीके का उपयोग करने के लिए और वाइल्ड-कार्ड का उपयोग कब करना है?

मैं OracleDocGenericMethod से सामान्य तरीकों के बारे में पढ़ रहा हूँ। मैं तुलना के बारे में काफी उलझन में हूँ जब यह कहता है कि वाइल्ड-कार्ड का उपयोग कब किया जाए और सामान्य तरीकों का उपयोग कब किया जाए दस्तावेज़ से उद्धरित

interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); } 

इसके बजाय हम सामान्य तरीकों का इस्तेमाल कर सकते थे:

 interface Collection<E> { public <T> boolean containsAll(Collection<T> c); public <T extends E> boolean addAll(Collection<T> c); // Hey, type variables can have bounds too! } 

[…] यह हमें बताता है कि प्रकार तर्क बहुलोफिज़्म के लिए उपयोग किया जा रहा है; इसका एकमात्र प्रभाव विभिन्न अभिविन्यास साइटों पर विभिन्न तर्क प्रकारों का उपयोग करने की अनुमति देना है। यदि ऐसा है, तो आपको वाइल्डकार्ड का उपयोग करना चाहिए। वाइल्डकार्ड लचीला उप-प्रकार का समर्थन करने के लिए डिज़ाइन किए गए हैं, जो कि हम यहां व्यक्त करने का प्रयास कर रहे हैं।

क्या हम वाइल्ड कार्ड पसंद नहीं करते (Collection<? extends E> c); क्या बहुरूपता का भी समर्थन कर रहा है? तो क्यों सामान्य तरीके से उपयोग इस में अच्छा नहीं माना जाता है?

आगे बढ़ते हुए, यह कहता है,

सामान्य पद्धतियों और / या इसके रिटर्न प्रकार में एक या एक से अधिक तर्कों के प्रकारों के बीच निर्भरता को व्यक्त करने के लिए जेनेरिक तरीके का उपयोग करने के लिए प्रकार पैरामीटर की अनुमति दी जाती है। यदि ऐसी निर्भरता नहीं है, तो एक सामान्य विधि का उपयोग नहीं किया जाना चाहिए।

इसका क्या मतलब है?

उन्होंने उदाहरण प्रस्तुत किया है

 class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... } 

[…]

हम इस पद्धति के लिए हस्ताक्षर भी लिख सकते हैं, बिना वाइल्डकार्ड का उपयोग किए:

 class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... } 

दस्तावेज़ दूसरी घोषणा को हतोत्साहित करता है और पहले वाक्य रचना का उपयोग को बढ़ावा देता है? पहली और दूसरी घोषणा के बीच अंतर क्या है? दोनों ही बात कर रहे हैं?

क्या कोई इस क्षेत्र पर प्रकाश डाल सकता है

वेब के समाधान से एकत्रित समाधान "सामान्य तरीके का उपयोग करने के लिए और वाइल्ड-कार्ड का उपयोग कब करना है?"

कुछ जगहें हैं, जहां वाइल्डकार्ड और प्रकार पैरामीटर एक ही काम करते हैं लेकिन कुछ जगहें भी हैं, जहां आपको टाइप पैरामीटर का उपयोग करना पड़ता है।

  1. यदि आप विभिन्न प्रकार के विधि तर्कों पर कुछ रिश्ते को लागू करना चाहते हैं, तो आप ऐसा नहीं कर सकते कि वाइल्डकार्ड के साथ, आपको प्रकार पैरामीटर का उपयोग करना होगा

उदाहरण के तौर पर अपना तरीका लेना, मान लीजिए कि आप यह सुनिश्चित करना चाहते हैं कि copy() पद्धति का src और dest सूची पारित होनी चाहिए, आप इसे समान मानदंडों के साथ कर सकते हैं:

 public static <T extends Number> void copy(List<T> dest, List<T> src) 

यहां, आपको यह सुनिश्चित किया जाता है कि सूची के लिए दोनों dest और src का समान पैरामीटर वाला प्रकार है इसलिए, src से घटकों को कॉपी करने के लिए सुरक्षित है

लेकिन, यदि आप वाइल्डकार्ड का उपयोग करने के लिए विधि बदलने के लिए जाते हैं:

 public static void copy(List<? extends Number> dest, List<? extends Number> src) 

यह अपेक्षा के अनुरूप काम नहीं करेगा दूसरे मामले में, आप List<Integer> और List<Float> को dest और src रूप में पास कर सकते हैं। इसलिए, src से घटकों को आगे बढ़ने से अब और प्रकार सुरक्षित नहीं होगा। यदि आपको इस प्रकार के संबंध की आवश्यकता नहीं है, तो आप सभी प्रकार के मापदंडों का उपयोग न करें।

वाइल्डकार्ड और टाइप पैरामीटर का उपयोग करने के बीच कुछ अन्य अंतर हैं:

  • यदि आपके पास केवल एक पैरामीटर वाला प्रकार तर्क है, तो आप वाइल्डकार्ड का उपयोग कर सकते हैं, हालांकि प्रकार पैरामीटर भी काम करेगा।
  • टाइप पैरामीटर एकाधिक सीमाओं का समर्थन करते हैं, वाइल्डकार्ड नहीं करते हैं।
  • वाइल्डकार्ड दोनों ऊपरी और निचले सीमा का समर्थन करते हैं, प्रकार पैरामीटर केवल ऊपरी सीमा का समर्थन करते हैं इसलिए, यदि आप किसी विधि को परिभाषित करना चाहते हैं जो कि List की Integer या सुपर वर्ग है, तो आप ऐसा कर सकते हैं:

     public void print(List<? super Integer> list) // OK 

    लेकिन आप प्रकार पैरामीटर का उपयोग नहीं कर सकते हैं:

      public <T super Integer> void print(List<T> list) // Won't compile 

संदर्भ:

  • एंजेलिका लैंगर के जावा जेनेरिएक्स के सामान्य प्रश्न

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

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

 public <T> T giveMeMaximum(Collection<T> items); public <T> Collection<T> applyFilter(Collection<T> items); 

यहां आप कुछ निश्चित मानदंडों के बाद टी में से कुछ निकाल रहे हैं। यदि टी Long आपके तरीके Long और Collection<Long> लौटेगा Collection<Long> ; वास्तविक रिटर्न प्रकार पैरामीटर प्रकार पर निर्भर है, इस प्रकार यह उपयोगी है, और सलाह दी है, सामान्य प्रकारों का उपयोग करने के लिए।

जब ऐसा नहीं है, तो आप वाइल्ड कार्ड प्रकार का उपयोग कर सकते हैं:

 public int count(Collection<?> items); public boolean containsDuplicate(Collection<?> items); 

इस दो उदाहरणों में जो भी संग्रह के आइटम का प्रकार होता है, वापसी प्रकार int और boolean

आपके उदाहरणों में:

 interface Collection<E> { public boolean containsAll(Collection<?> c); public boolean addAll(Collection<? extends E> c); } 

उन दोनों फ़ंक्शंस एक बूलियन वापस लौट आएंगे जो संग्रह में वस्तुओं के प्रकार हैं। दूसरे मामले में यह ई के उप-वर्ग के उदाहरणों तक सीमित है।

दूसरा सवाल:

 class Collections { public static <T> void copy(List<T> dest, List<? extends T> src) { ... } 

यह पहला कोड आपको एक विषम List<? extends T> src पास करने की अनुमति देता है List<? extends T> src एक पैरामीटर के रूप में List<? extends T> src को List<? extends T> src इस सूची में विभिन्न कक्षाओं के कई तत्व शामिल हो सकते हैं, जब तक कि वे सभी आधार वर्ग T.

अगर आप के पास था:

 interface Fruit{} 

तथा

 class Apple implements Fruit{} class Pear implements Fruit{} class Tomato implements Fruit{} 

तुम यह कर सकते थे

 List<? extends Fruit> basket = new ArrayList<? extends Fruit>(); basket.add(new Apple()); basket.add(new Pear()); basket.add(new Tomato()); List<Fruit> fridge = new ArrayList<Fruit>(); Collections.copy(fridge, basket);// works 

दूसरी ओर

 class Collections { public static <T, S extends T> void copy(List<T> dest, List<S> src) { ... } 

List<S> src को एक विशेष वर्ग के होने के लिए रोकें जो कि टी के एक उप-वर्ग है। सूची में केवल एक वर्ग के तत्व (इस उदाहरण में एस) और कोई अन्य वर्ग ही शामिल नहीं हो सकते हैं, भले ही वे टी भी लागू करें। आप मेरे पिछले उदाहरण का उपयोग नहीं कर पाएंगे लेकिन आप ऐसा कर सकते हैं:

 List<Apple> basket = new ArrayList<Apple>(); basket.add(new Apple()); basket.add(new Apple()); basket.add(new Apple()); List<Fruit> fridge = new ArrayList<Fruit>(); Collections.copy(fridge, basket); /* works since the basket is defined as a List of apples and not a list of some fruits. */ 

वाइल्डकार्ड पद्धति भी सामान्य है – आप इसे कुछ प्रकार के प्रकारों के साथ कॉल कर सकते हैं

<T> वाक्यविन्यास एक प्रकार चर नाम परिभाषित करता है यदि एक प्रकार की चर का कोई उपयोग होता है (उदाहरण के लिए विधि क्रियान्वयन में या अन्य प्रकार के लिए बाधा के रूप में), तो इसका नाम समझना चाहिए, अन्यथा आप उपयोग कर सकते हैं ? , अनाम चर के रूप में तो, सिर्फ एक छोटी कट की तरह लग रहा है

इसके अलावा, यह ? सिंटैक्स परिहार्य नहीं है जब आप एक फ़ील्ड घोषित करते हैं:

 class NumberContainer { Set<? extends Number> numbers; } 

मैं कोशिश करूँगा और एक-एक करके अपने प्रश्न का उत्तर दूंगा

क्या हम वाइल्ड कार्ड पसंद नहीं करते (Collection<? extends E> c); क्या बहुरूपता का भी समर्थन कर रहा है?

नहीं। कारण यह है कि बाध्य वाइल्डकार्ड में कोई निर्धारित पैरामीटर प्रकार नहीं है यह एक अज्ञात है यह सभी "जानता है" कि "रोकथाम" एक प्रकार E (जो भी परिभाषित किया गया है) का है इसलिए, यह सत्यापित नहीं किया जा सकता है कि क्या प्रदान की गई मान सीमाबद्ध प्रकार से मेल खाती है या नहीं।

इसलिए, वाइल्डकार्ड पर बहुरूपृत व्यवहार करने के लिए यह समझदार नहीं है।

दस्तावेज़ दूसरी घोषणा को हतोत्साहित करता है और पहले वाक्य रचना का उपयोग को बढ़ावा देता है? पहली और दूसरी घोषणा के बीच अंतर क्या है? दोनों ही बात कर रहे हैं?

पहला विकल्प इस मामले में बेहतर होता है क्योंकि T हमेशा बाध्य होता है, और source निश्चित रूप से मूल्यों (अज्ञात की) होगा जो कि उप-कक्षाओं में T

इसलिए, मान लें कि आप सभी नंबरों की सूची कॉपी करना चाहते हैं, पहला विकल्प होगा

 Collections.copy(List<Number> dest, List<? extends Number> src); 

src , अनिवार्य रूप से, List<Double> , List<Float> , आदि को स्वीकार कर सकता है क्योंकि वहाँ पैरामीटर वाले प्रकार के लिए ऊपरी बाध्यता है।

दूसरा विकल्प आपको हर प्रकार की प्रतिलिपि बनाने के लिए S को बाँध करने के लिए बाध्य करेगा, जैसे आप

 //For double Collections.copy(List<Number> dest, List<Double> src); //Double extends Number. //For int Collections.copy(List<Number> dest, List<Integer> src); //Integer extends Number. 

चूंकि S एक पैरामीटर वाला प्रकार है जो बाध्यकारी है।

आशा है कि ये आपकी मदद करेगा।

नीचे जेम्स गोस्लिंग 4th संस्करण द्वारा जावा प्रोग्रामिंग से निम्नलिखित उदाहरण पर विचार करें जहां हम 2 SinglyLinkQueue को विलय करना चाहते हैं:

 public static <T1, T2 extends T1> void merge(SinglyLinkQueue<T1> d, SinglyLinkQueue<T2> s){ // merge s element into d } public static <T> void merge(SinglyLinkQueue<T> d, SinglyLinkQueue<? extends T> s){ // merge s element into d } 

उपर्युक्त दोनों विधियों में एक ही कार्यक्षमता है तो क्या बेहतर है? उत्तर दूसरा है लेखक के अपने शब्दों में:

"सामान्य नियम वाइल्डकार्ड का उपयोग करना है, जब आप कर सकते हैं, क्योंकि वाइल्डकार्ड के साथ कोड आमतौर पर कई प्रकार के मापदंडों के साथ कोड की तुलना में अधिक पठनीय है.जब आपको एक प्रकार की वैरिएबल की ज़रूरत होती है, तो तय करें कि उस प्रकार की चर दो या दो से अधिक पैरामीटर को संबोधित करने के लिए प्रयोग किया जाता है, या वापसी प्रकार के साथ एक पैरामीटर प्रकार से संबंधित हो। यदि उत्तर नहीं है, तो वाइल्डकार्ड पर्याप्त होगा। "

नोट: पुस्तक में केवल दूसरी विधि दी जाती है और पैरामीटर का नाम 'टी' के बजाय एस है पुस्तक में पहले विधि नहीं है

एक अन्य अंतर जो यहाँ सूचीबद्ध नहीं है

 static <T> void fromArrayToCollection(T[] a, Collection<T> c) { for (T o : a) { c.add(o); // correct } } 

लेकिन निम्नलिखित के परिणाम समय के संकलन में होंगे।

 static <T> void fromArrayToCollection(T[] a, Collection<?> c) { for (T o : a) { c.add(o); // compile time error } }