जावा में जेनेरिक: Difference between revisions

From Vigyanwiki
(Created page with "{{Short description|Form of abstraction for a type or method to allow them to be functions of a type parameter}} जेनरिक सामान्य प्रोग्...")
 
No edit summary
Line 1: Line 1:
{{Short description|Form of abstraction for a type or method to allow them to be functions of a type parameter}}
{{Short description|Form of abstraction for a type or method to allow them to be functions of a type parameter}}
जेनरिक [[सामान्य प्रोग्रामिंग]] की एक सुविधा है जिसे 2004 में जावा प्लेटफ़ॉर्म, मानक संस्करण 5.0 के भीतर [[जावा (प्रोग्रामिंग भाषा)]] में जोड़ा गया था। उन्हें संकलन-समय प्रकार की सुरक्षा प्रदान करते हुए विभिन्न प्रकार की वस्तुओं पर एक प्रकार या विधि को संचालित करने की अनुमति देने के लिए जावा के [[प्रकार प्रणाली]] का विस्तार करने के लिए डिज़ाइन किया गया था।<ref>[http://java.sun.com/j2se/1.5.0/docs/guide/language/index.html Java Programming Language]</ref> पहलू [[संकलन-समय प्रकार की सुरक्षा]] पूरी तरह से हासिल नहीं की गई थी, क्योंकि 2016 में यह दिखाया गया था कि सभी मामलों में इसकी गारंटी नहीं है।<ref>A ClassCastException can be thrown even in the absence of casts or nulls.{{cite web|url=https://raw.githubusercontent.com/namin/unsound/master/doc/unsound-oopsla16.pdf|title=Java and Scala's Type Systems are Unsound}}</ref>{{sfn|Bloch|2018|loc=Chapter §5 Item 27: Eliminate unchecked warnings|pp=123-125}}
जेनरिक [[सामान्य प्रोग्रामिंग]] की एक सुविधा है, जिसे 2004 में जावा प्लेटफ़ॉर्म, मानक संस्करण 5.0 के अन्दर [[जावा (प्रोग्रामिंग भाषा)]] में जोड़ा गया था। उन्हें संकलन-समय प्रकार की सुरक्षा प्रदान करते हुए विभिन्न प्रकार की वस्तुओं पर एक प्रकार या विधि को संचालित करने की अनुमति देने के लिए जावा के [[प्रकार प्रणाली]] का विस्तार करने के लिए डिज़ाइन किया गया था।<ref>[http://java.sun.com/j2se/1.5.0/docs/guide/language/index.html Java Programming Language]</ref> पहलू [[संकलन-समय प्रकार की सुरक्षा]] पूरी तरह से प्राप्त नहीं की गई थी, क्योंकि 2016 में यह दिखाया गया था कि सभी स्थितियों में इसकी गारंटी नहीं है।<ref>A ClassCastException can be thrown even in the absence of casts or nulls.{{cite web|url=https://raw.githubusercontent.com/namin/unsound/master/doc/unsound-oopsla16.pdf|title=Java and Scala's Type Systems are Unsound}}</ref>{{sfn|Bloch|2018|loc=Chapter §5 Item 27: Eliminate unchecked warnings|pp=123-125}}


जावा संग्रह ढाँचा संग्रह उदाहरण में संग्रहीत वस्तुओं के प्रकार को निर्दिष्ट करने के लिए जेनेरिक का समर्थन करता है।
जावा संग्रह ढाँचा संग्रह उदाहरण में संग्रहीत वस्तुओं के प्रकार को निर्दिष्ट करने के लिए जेनेरिक का समर्थन करता है।


1998 में, [[गिलाद ब्राचा]], [[ मार्टिन ओडर्सकी ]], डेविड स्टाउटमायर और [[फिलिप वाडलर]] ने जेनेरिक जावा बनाया, जो सामान्य प्रकारों का समर्थन करने के लिए जावा भाषा का एक विस्तार था।<ref>[http://homepages.inf.ed.ac.uk/wadler/gj/ GJ: Generic Java]</ref> जेनेरिक जावा को [[वाइल्डकार्ड (जावा)]] के साथ जावा में शामिल किया गया था।
1998 में, [[गिलाद ब्राचा]], [[ मार्टिन ओडर्सकी ]], डेविड स्टाउटमायर और [[फिलिप वाडलर]] ने जेनेरिक जावा बनाया, जो सामान्य प्रकारों का समर्थन करने के लिए जावा भाषा का एक विस्तार था।<ref>[http://homepages.inf.ed.ac.uk/wadler/gj/ GJ: Generic Java]</ref> जेनेरिक जावा को [[वाइल्डकार्ड (जावा)]] के साथ जावा में सम्मिलित किया गया था।


==पदानुक्रम और वर्गीकरण==
==पदानुक्रम और वर्गीकरण==
जावा भाषा विशिष्टता के अनुसार:<ref>[http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html Java Language Specification, Third Edition]
जावा भाषा विशिष्टता के अनुसार:<ref>[http://java.sun.com/docs/books/jls/third_edition/html/j3TOC.html Java Language Specification, Third Edition]
by James Gosling, Bill Joy, Guy Steele, Gilad Bracha – Prentice Hall PTR 2005</ref>
by James Gosling, Bill Joy, Guy Steele, Gilad Bracha – Prentice Hall PTR 2005</ref>
*एक प्रकार का चर एक अयोग्य पहचानकर्ता है। [[ प्रकार चर ]]्स को जेनेरिक क्लास डिक्लेरेशन, जेनेरिक इंटरफ़ेस डिक्लेरेशन, जेनेरिक मेथड डिक्लेरेशन और जेनेरिक कंस्ट्रक्टर डिक्लेरेशन द्वारा पेश किया जाता है।
*एक प्रकार का चर एक अयोग्य पहचानकर्ता है। [[ प्रकार चर | प्रकार चर]] को जेनेरिक क्लास डिक्लेरेशन, जेनेरिक इंटरफ़ेस डिक्लेरेशन, जेनेरिक मेथड डिक्लेरेशन और जेनेरिक कंस्ट्रक्टर डिक्लेरेशन द्वारा प्रस्तुत किया जाता है।
*एक वर्ग सामान्य है यदि वह एक या अधिक प्रकार के चर घोषित करता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है जो पैरामीटर के रूप में कार्य करते हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} एक सामान्य वर्ग घोषणा पैरामीटरयुक्त प्रकारों के एक सेट को परिभाषित करती है, जो प्रकार पैरामीटर अनुभाग के प्रत्येक संभावित आह्वान के लिए एक है। ये सभी पैरामीटरयुक्त प्रकार रनटाइम पर एक ही क्लास साझा करते हैं।
*एक वर्ग सामान्य है, यदि वह एक या अधिक प्रकार के चर घोषित करता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है, जो पैरामीटर के रूप में कार्य करते हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} एक सामान्य वर्ग घोषणा पैरामीटरयुक्त प्रकारों के एक सेट को परिभाषित करती है, जो प्रकार पैरामीटर अनुभाग के प्रत्येक संभावित आह्वान के लिए एक है। ये सभी पैरामीटरयुक्त प्रकार रनटाइम पर एक ही क्लास साझा करते हैं।
*एक [[इंटरफ़ेस (जावा)]] सामान्य है यदि यह एक या अधिक प्रकार के चर घोषित करता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है जो पैरामीटर के रूप में कार्य करते हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} एक सामान्य इंटरफ़ेस घोषणा प्रकार के एक सेट को परिभाषित करती है, प्रकार पैरामीटर अनुभाग के प्रत्येक संभावित आह्वान के लिए एक। सभी पैरामीटरयुक्त प्रकार रनटाइम पर समान इंटरफ़ेस साझा करते हैं।
*एक [[इंटरफ़ेस (जावा)]] सामान्य है यदि यह एक या अधिक प्रकार के चर घोषित करता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है, जो पैरामीटर के रूप में कार्य करते हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} एक सामान्य इंटरफ़ेस घोषणा प्रकार के एक सेट को परिभाषित करती है, प्रकार पैरामीटर अनुभाग के प्रत्येक संभावित आह्वान के लिए एक। सभी पैरामीटरयुक्त प्रकार रनटाइम पर समान इंटरफ़ेस साझा करते हैं।
*एक विधि सामान्य है यदि यह एक या अधिक प्रकार के चर घोषित करती है।{{sfn|Bloch|2018|loc=Chapter §5 Item 30: Favor generic methods|pp=135-138}} इस प्रकार के चर को विधि के औपचारिक प्रकार के पैरामीटर के रूप में जाना जाता है। औपचारिक प्रकार पैरामीटर सूची का रूप किसी वर्ग या इंटरफ़ेस के प्रकार पैरामीटर सूची के समान है।
*एक विधि सामान्य है यदि यह एक या अधिक प्रकार के चर घोषित करती है।{{sfn|Bloch|2018|loc=Chapter §5 Item 30: Favor generic methods|pp=135-138}} इस प्रकार के चर को विधि के औपचारिक प्रकार के पैरामीटर के रूप में जाना जाता है। औपचारिक प्रकार पैरामीटर सूची का रूप किसी वर्ग या इंटरफ़ेस के प्रकार पैरामीटर सूची के समान है।
*एक कंस्ट्रक्टर को जेनेरिक घोषित किया जा सकता है, चाहे कंस्ट्रक्टर को जिस वर्ग में घोषित किया गया है वह स्वयं जेनेरिक है या नहीं। एक कंस्ट्रक्टर सामान्य होता है यदि वह एक या अधिक प्रकार के वेरिएबल घोषित करता है। इन प्रकार के चर को कंस्ट्रक्टर के औपचारिक प्रकार के पैरामीटर के रूप में जाना जाता है। औपचारिक प्रकार पैरामीटर सूची का रूप सामान्य वर्ग या इंटरफ़ेस की प्रकार पैरामीटर सूची के समान है।
*एक कंस्ट्रक्टर को जेनेरिक घोषित किया जा सकता है, चाहे कंस्ट्रक्टर को जिस वर्ग में घोषित किया गया है वह स्वयं जेनेरिक है या नहीं। एक कंस्ट्रक्टर सामान्य होता है यदि वह एक या अधिक प्रकार के वेरिएबल घोषित करता है। इन प्रकार के चर को कंस्ट्रक्टर के औपचारिक प्रकार के पैरामीटर के रूप में जाना जाता है। औपचारिक प्रकार पैरामीटर सूची का रूप सामान्य वर्ग या इंटरफ़ेस की प्रकार पैरामीटर सूची के समान है।


==प्रेरणा==
==प्रेरणा==
जावा कोड का निम्नलिखित ब्लॉक उस समस्या को दर्शाता है जो जेनेरिक का उपयोग न करने पर मौजूद होती है। सबसे पहले, यह एक घोषणा करता है{{Javadoc:SE|name=ArrayList|package=java.util|java/util|ArrayList}} प्रकार का{{Javadoc:SE|name=Object|package=java.lang|java/lang|Object}}. फिर, यह एक जोड़ता है <code>String</code> तक <code>ArrayList</code>. अंत में, यह जोड़े गए को पुनः प्राप्त करने का प्रयास करता है <code>String</code> और इसे एक पर डालें <code>Integer</code>-तर्क में एक त्रुटि, क्योंकि आम तौर पर एक पूर्णांक में एक मनमाना स्ट्रिंग डालना संभव नहीं है।
जावा कोड का निम्नलिखित ब्लॉक उस समस्या को दर्शाता है जो जेनेरिक का उपयोग न करने पर उपलब्ध होती है। सबसे पहले, यह {{Javadoc:SE|name=Object|package=java.lang|java/lang|Object}} प्रकार की {{Javadoc:SE|name=ArrayList|package=java.util|java/util|ArrayList}} घोषित करता है। फिर, यह <code>ArrayList</code> में <code>String</code> जोड़ता है। अंत में, यह जोड़े गए <code>String</code> को पुनः प्राप्त करने का प्रयास करता है और इसे <code>Integer</code> में डालने का प्रयास करता है - तर्क में एक त्रुटि, क्योंकि सामान्यतः एक पूर्णांक में इच्छानुसार स्ट्रिंग डालना संभव नहीं है।


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 23: Line 23:
final Integer i = (Integer) v.get(0); // Run time error
final Integer i = (Integer) v.get(0); // Run time error
</syntaxhighlight>
</syntaxhighlight>
हालाँकि कोड बिना किसी त्रुटि के संकलित किया गया है, यह एक रनटाइम अपवाद फेंकता है (<code>java.lang.ClassCastException</code>) कोड की तीसरी पंक्ति निष्पादित करते समय। जेनरिक का उपयोग करके संकलन समय के दौरान इस प्रकार की तर्क त्रुटि का पता लगाया जा सकता है{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} और उनका उपयोग करने के लिए प्राथमिक प्रेरणा है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है जो पैरामीटर के रूप में कार्य करते हैं।
चूँकि कोड बिना किसी त्रुटि के संकलित किया गया है, यह कोड की तीसरी पंक्ति निष्पादित करते समय एक रनटाइम अपवाद (<code>java.lang.ClassCastException</code>) फेंकता है। जेनरिक का उपयोग करके संकलन समय के समय इस प्रकार की तर्क त्रुटि का पता लगाया जा सकता है{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} और उनका उपयोग करने के लिए प्राथमिक प्रेरणा है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है, जो पैरामीटर के रूप में कार्य करते हैं।


उपरोक्त कोड खंड को जेनेरिक का उपयोग करके निम्नानुसार फिर से लिखा जा सकता है:
उपरोक्त कोड खंड को जेनेरिक का उपयोग करके निम्नानुसार फिर से लिखा जा सकता है:
Line 32: Line 32:
final Integer i = (Integer) v.get(0); // (type error)  compilation-time error
final Integer i = (Integer) v.get(0); // (type error)  compilation-time error
</syntaxhighlight>
</syntaxhighlight>
प्रकार पैरामीटर <code>String</code> कोण कोष्ठक के भीतर घोषित करता है <code>ArrayList</code> का गठन किया जाना है <code>String</code> (का एक वंशज <code>ArrayList</code>सामान्य है <code>Object</code> घटक)जेनेरिक के साथ, तीसरी पंक्ति को किसी विशेष प्रकार में डालना अब आवश्यक नहीं है, क्योंकि इसका परिणाम <code>v.get(0)</code> परिभाषित किया जाता है <code>String</code> कंपाइलर द्वारा उत्पन्न कोड द्वारा.
कोण कोष्ठक के अन्दर टाइप पैरामीटर <code>String</code> <code>ArrayList</code> को <code>String</code> (<code>ArrayList</code> के सामान्य <code>Object</code> घटकों का वंशज) से गठित होने की घोषणा करता है। जेनेरिक के साथ, तीसरी पंक्ति को किसी विशेष प्रकार में डालना अब आवश्यक नहीं है, क्योंकि <code>v.get(0)</code> के परिणाम को कंपाइलर द्वारा उत्पन्न कोड द्वारा <code>String</code> के रूप में परिभाषित किया गया है।


इस खंड की तीसरी पंक्ति में तार्किक दोष को संकलन समय|संकलन-समय त्रुटि (J2SE 5.0 या बाद के संस्करण के साथ) के रूप में पता लगाया जाएगा क्योंकि संकलक इसका पता लगाएगा <code>v.get(0)</code> रिटर्न <code>String</code> के बजाय <code>Integer</code>.{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} अधिक विस्तृत उदाहरण के लिए, संदर्भ देखें।<ref>{{cite web |url=http://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf |title=जावा प्रोग्रामिंग भाषा में जेनेरिक|author=Gilad Bracha |date=July 5, 2004 |website=www.oracle.com}}</ref>
इस खंड की तीसरी पंक्ति में तार्किक दोष को संकलन-समय त्रुटि (J2SE 5.0 या बाद के संस्करण के साथ) के रूप में पहचाना जाएगा क्योंकि कंपाइलर यह पता लगाएगा कि <code>v.get(0)</code> <code>Integer</code> पूर्णांक के अतिरिक्त <code>String</code> लौटाता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} अधिक विस्तृत उदाहरण के लिए, संदर्भ देखें।<ref>{{cite web |url=http://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf |title=जावा प्रोग्रामिंग भाषा में जेनेरिक|author=Gilad Bracha |date=July 5, 2004 |website=www.oracle.com}}</ref>
यहां इंटरफ़ेस की परिभाषा का एक छोटा सा अंश दिया गया है{{Javadoc:SE|package=java.util|java/util|List}} और{{Javadoc:SE|package=java.util|java/util|Iterator}} पैकेज में{{Javadoc:SE|package=java.util|java/util}}:
 
यहां पैकेज {{Javadoc:SE|package=java.util|java/util}} में इंटरफेस {{Javadoc:SE|package=java.util|java/util|List}} और {{Javadoc:SE|package=java.util|java/util|Iterator}} की परिभाषा से एक छोटा सा अंश दिया गया है:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 82: Line 83:
}
}
</syntaxhighlight>
</syntaxhighlight>
इस सामान्य वर्ग का उपयोग निम्नलिखित तरीकों से किया जा सकता है, उदाहरण के लिए:
इस सामान्य वर्ग का उपयोग निम्नलिखित विधियों से किया जा सकता है, उदाहरण के लिए:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 98: Line 99:
}
}
</syntaxhighlight>
</syntaxhighlight>
यह आउटपुट देता है:
यह आउटपुट देता है:<syntaxhighlight>
<पूर्व>
grade: (Mike, A)
ग्रेड: (माइक, )
mark: (Mike, 100)
निशान: (माइक, 100)
13 is prime.
13 अभाज्य है.
</syntaxhighlight>
</पूर्व>


==सामान्य विधि परिभाषाएँ==
==सामान्य विधि परिभाषाएँ==
Line 112: Line 112:
}
}
</syntaxhighlight>
</syntaxhighlight>
नोट: यदि हम पहले को हटा दें <code><Type></code> उपरोक्त विधि में, हमें संकलन त्रुटि मिलेगी (प्रतीक प्रकार नहीं मिल सका), क्योंकि यह प्रतीक की घोषणा का प्रतिनिधित्व करता है।
नोट: यदि हम पहले <code><Type></code> को हटा दें, उपरोक्त विधि में, हमें संकलन त्रुटि मिलेगी (प्रतीक प्रकार नहीं मिल सका), क्योंकि यह प्रतीक की घोषणा का प्रतिनिधित्व करता है।


कई मामलों में, विधि के उपयोगकर्ता को प्रकार के मापदंडों को इंगित करने की आवश्यकता नहीं होती है, क्योंकि उनका अनुमान लगाया जा सकता है:
कई स्थितियों में, विधि के उपयोगकर्ता को प्रकार के मापदंडों को इंगित करने की आवश्यकता नहीं होती है, क्योंकि उनका अनुमान लगाया जा सकता है:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 124: Line 124:
final Entry<String, String> pair = Entry.<String>twice("Hello");
final Entry<String, String> pair = Entry.<String>twice("Hello");
</syntaxhighlight>
</syntaxhighlight>
[[आदिम प्रकार]]ों के उपयोग की अनुमति नहीं है, और इसके बजाय ऑब्जेक्ट प्रकार (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग)#बॉक्सिंग संस्करणों का उपयोग किया जाना चाहिए:
[[आदिम प्रकार]] के उपयोग की अनुमति नहीं है, और इसके अतिरिक्त ऑब्जेक्ट प्रकार (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) बॉक्सिंग संस्करणों का उपयोग किया जाना चाहिए:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
final Entry<int, int> pair; // Fails compilation. Use Integer instead.
final Entry<int, int> pair; // Fails compilation. Use Integer instead.
</syntaxhighlight>
</syntaxhighlight>
दिए गए मापदंडों के आधार पर सामान्य तरीके बनाने की भी संभावना है।
दिए गए मापदंडों के आधार पर सामान्य विधि बनाने की भी संभावना है।


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 136: Line 136:
}
}
</syntaxhighlight>
</syntaxhighlight>
ऐसे मामलों में आप आदिम प्रकारों का भी उपयोग नहीं कर सकते, उदाहरण के लिए:
ऐसी स्थितियों में आप आदिम प्रकारों का भी उपयोग नहीं कर सकते, उदाहरण के लिए:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 144: Line 144:


==डायमंड ऑपरेटर==
==डायमंड ऑपरेटर==
प्रकार अनुमान के लिए धन्यवाद, जावा एसई 7 और इसके बाद के संस्करण प्रोग्रामर को कोण कोष्ठक की एक खाली जोड़ी को प्रतिस्थापित करने की अनुमति देते हैं (<code>&lt;&gt;</code>, जिसे डायमंड ऑपरेटर कहा जाता है) कोण कोष्ठक की एक जोड़ी के लिए जिसमें एक या अधिक प्रकार के पैरामीटर होते हैं जो पर्याप्त रूप से बंद संदर्भ प्रकार रूपांतरण # अंतर्निहित प्रकार रूपांतरण करते हैं।<ref>{{cite web | url=http://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html | title=Type Inference for Generic Instance Creation }}</ref> इस प्रकार, उपरोक्त कोड उदाहरण का उपयोग करना <code>Entry</code> इस प्रकार पुनः लिखा जा सकता है:
प्रकार के अनुमान के लिए धन्यवाद, जावा एसई 7 और इसके बाद के संस्करण प्रोग्रामर को कोण कोष्ठक की एक खाली जोड़ी (<code>&lt;&gt;</code>, जिसे डायमंड ऑपरेटर कहा जाता है) को कोण कोष्ठक की एक जोड़ी के लिए प्रतिस्थापित करने की अनुमति देता है जिसमें एक या अधिक प्रकार के पैरामीटर होते हैं जो पर्याप्त रूप से बंद संदर्भ का तात्पर्य है।<ref>{{cite web | url=http://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html | title=Type Inference for Generic Instance Creation }}</ref> इस प्रकार, <code>Entry</code> का उपयोग करके उपरोक्त कोड उदाहरण को इस प्रकार पुनः लिखा जा सकता है:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 159: Line 159:


==वाइल्डकार्ड टाइप करें==
==वाइल्डकार्ड टाइप करें==
{{main|Wildcard (Java)}}
{{main|वाइल्डकार्ड (जावा)}}
पैरामीटरयुक्त प्रकार के लिए एक प्रकार का तर्क किसी ठोस वर्ग या इंटरफ़ेस तक सीमित नहीं है। जावा पैरामीटरयुक्त प्रकारों के लिए प्रकार के तर्क के रूप में टाइप वाइल्डकार्ड के उपयोग की अनुमति देता है। वाइल्डकार्ड प्रपत्र में प्रकार के तर्क हैं<code><?></code>; वैकल्पिक रूप से ऊपरी या निचले सीमाबद्ध परिमाणीकरण के साथ। यह देखते हुए कि वाइल्डकार्ड द्वारा दर्शाया गया सटीक प्रकार अज्ञात है, उन तरीकों के प्रकार पर प्रतिबंध लगाए जाते हैं जिन्हें किसी ऑब्जेक्ट पर बुलाया जा सकता है जो पैरामीटरयुक्त प्रकारों का उपयोग करता है।
 
पैरामीटरयुक्त प्रकार के लिए एक प्रकार का तर्क किसी ठोस वर्ग या इंटरफ़ेस तक सीमित नहीं है। जावा पैरामीटरयुक्त प्रकारों के लिए प्रकार के तर्क के रूप में "टाइप वाइल्डकार्ड" के उपयोग की अनुमति देता है। वाइल्डकार्ड "<code><?></code>" रूप में प्रकार के तर्क हैं; वैकल्पिक रूप से ऊपरी या निचली सीमा के साथ। यह देखते हुए कि वाइल्डकार्ड द्वारा दर्शाया गया स्पष्ट प्रकार अज्ञात है, उन विधियों के प्रकार पर प्रतिबंध लगाए जाते हैं जिन्हें किसी ऑब्जेक्ट पर बुलाया जा सकता है जो पैरामीटरयुक्त प्रकारों का उपयोग करता है।


यहां एक उदाहरण दिया गया है जहां तत्व प्रकार a <code>Collection<E></code> वाइल्डकार्ड द्वारा पैरामीटराइज़ किया गया है:
यहां एक उदाहरण दिया गया है जहां <code>Collection<E></code> के तत्व प्रकार को वाइल्डकार्ड द्वारा पैरामीटराइज़ किया गया है:


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Line 168: Line 169:
c.add(new Object()); // compile-time error
c.add(new Object()); // compile-time error
c.add(null); // allowed</syntaxhighlight>
c.add(null); // allowed</syntaxhighlight>
चूँकि हम नहीं जानते कि तत्व किस प्रकार का है <code>c</code> का अर्थ है, हम इसमें ऑब्जेक्ट नहीं जोड़ सकते। <code>add()</code> e> विधि प्रकार के तर्क लेती है <code>E</code>, का तत्व प्रकार <code>Collection<E></code> सामान्य इंटरफ़ेस. जब वास्तविक प्रकार का तर्क है <code>?</code>, यह किसी अज्ञात प्रकार का प्रतीक है। हम किसी भी विधि तर्क मान को पास करते हैं <code>add()</code> विधि को इस अज्ञात प्रकार का एक उपप्रकार होना होगा। चूँकि हम नहीं जानते कि वह किस प्रकार का है, हम कुछ भी पास नहीं कर सकते। एकमात्र अपवाद शून्य सूचक है; जो हर प्रकार का सदस्य है.<ref>{{cite web |url=http://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf |title=जावा प्रोग्रामिंग भाषा में जेनेरिक|author=Gilad Bracha |date=July 5, 2004 |pages=5 |website=www.oracle.com}}</ref>
चूँकि हम नहीं जानते कि तत्व प्रकार <code>c</code> का क्या अर्थ है, हम इसमें ऑब्जेक्ट नहीं जोड़ सकते। <code>add()</code> विधि <code>E</code> e> प्रकार के तर्क लेती है, जो कि <code>Collection<E></code> जेनेरिक इंटरफ़ेस का तत्व प्रकार है। जब वास्तविक प्रकार का तर्क <code>?</code> होता है, तो यह किसी अज्ञात प्रकार का प्रतिनिधित्व करता है। <code>add()</code> विधि में हम जो भी विधि तर्क मान पास करते हैं वह इस अज्ञात प्रकार का उपप्रकार होना चाहिए। चूँकि हम नहीं जानते कि वह किस प्रकार का है, हम कुछ भी पारित नहीं कर सकते हैं। एकमात्र अपवाद शून्य है; जो हर प्रकार का सदस्य है।<ref>{{cite web |url=http://www.oracle.com/technetwork/java/javase/generics-tutorial-159168.pdf |title=जावा प्रोग्रामिंग भाषा में जेनेरिक|author=Gilad Bracha |date=July 5, 2004 |pages=5 |website=www.oracle.com}}</ref>
किसी प्रकार के वाइल्डकार्ड की सीमाबद्ध मात्रा निर्दिष्ट करने के लिए, {{java|extends}} कीवर्ड का उपयोग यह इंगित करने के लिए किया जाता है कि प्रकार तर्क बाउंडिंग क्लास का एक उपप्रकार है।{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} इसलिए {{java|List<? extends Number>}} का अर्थ है कि दी गई सूची में कुछ अज्ञात प्रकार की वस्तुएं शामिल हैं जो इसका विस्तार करती हैं <code>Number</code> कक्षा। उदाहरण के लिए, सूची हो सकती है <code>List&lt;Float&gt;</code> या <code>List&lt;Number&gt;</code>. सूची से किसी तत्व को पढ़ने पर एक परिणाम प्राप्त होगा <code>Number</code>. फिर से, अशक्त तत्वों को जोड़ने की भी अनुमति है।<ref>{{Cite web |url=https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html |title=Wildcards > Bonus > Generics |last=Bracha |first=Gilad |author-link=Gilad Bracha |publisher=Oracle |website=The Java™ Tutorials |quote=...The sole exception is null, which is a member of every type...}}</ref>
 
उपरोक्त वाइल्डकार्ड का उपयोग लचीलापन जोड़ता है{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} चूंकि प्रकार के तर्क के रूप में ठोस प्रकार के साथ किन्हीं दो पैरामीटरयुक्त प्रकारों के बीच कोई वंशानुक्रम संबंध नहीं है। कोई भी नहीं <code>List<Number></code> और न <code>List<Integer></code> दूसरे का एक उपप्रकार है; चाहे <code>Integer</code> का एक उपप्रकार है <code>Number</code>.{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} तो, कोई भी तरीका जो अपनाता है <code>List<Number></code> एक पैरामीटर के रूप में किसी तर्क को स्वीकार नहीं करता है <code>List<Integer></code>. यदि ऐसा होता, तो इसे सम्मिलित करना संभव होता <code>Number</code> वह एक नहीं है <code>Integer</code> यह में; जो प्रकार की सुरक्षा का उल्लंघन करता है। यहां एक उदाहरण दिया गया है जो दर्शाता है कि यदि किस प्रकार की सुरक्षा का उल्लंघन किया जाएगा <code>List<Integer></code> का एक उपप्रकार थे <code>List<Number></code>:
किसी प्रकार के वाइल्डकार्ड की ऊपरी सीमा को निर्दिष्ट करने के लिए, {{java|extends}} कीवर्ड का उपयोग यह इंगित करने के लिए किया जाता है कि प्रकार तर्क बाउंडिंग क्लास का एक उपप्रकार है।{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} तो {{java|List<? extends Number>}} का अर्थ है कि दी गई सूची में कुछ अज्ञात प्रकार की वस्तुएं हैं जो <code>Number</code> वर्ग का विस्तार करती हैं। उदाहरण के लिए, सूची <code>List&lt;Float&gt;</code> या <code>List&lt;Number&gt;</code> हो सकती है। सूची से किसी तत्व को पढ़ने पर एक <code>Number</code> वापस आ जाएगी। फिर से, अशक्त तत्वों को जोड़ने की भी अनुमति है।<ref>{{Cite web |url=https://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html |title=Wildcards > Bonus > Generics |last=Bracha |first=Gilad |author-link=Gilad Bracha |publisher=Oracle |website=The Java™ Tutorials |quote=...The sole exception is null, which is a member of every type...}}</ref>
 
उपरोक्त वाइल्डकार्ड का उपयोग लचीलापन जोड़ता है{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} क्योंकि ठोस प्रकार के तर्क के साथ किन्हीं दो पैरामीटरयुक्त प्रकारों के बीच कोई विरासत संबंध नहीं है। न तो <code>List<Number></code> और न ही <code>List<Integer></code> दूसरे का उपप्रकार है; तथापि <code>Integer</code> <code>Number</code> का एक उपप्रकार है।{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} इसलिए, कोई भी विधि जो <code>List<Number></code> को एक पैरामीटर के रूप में लेती है, <code>List<Integer></code> के तर्क को स्वीकार नहीं करती है। यदि ऐसा होता, तो इसमें एक ऐसा <code>Number</code> सम्मिलित करना संभव होता जो <code>Integer</code> नहीं है; जो प्रकार की सुरक्षा का उल्लंघन करता है। यहां एक उदाहरण दिया गया है जो दर्शाता है कि यदि <code>List<Integer></code> <code>List<Number></code> का एक उपप्रकार होता तो किस प्रकार प्रकार की सुरक्षा का उल्लंघन किया जाता:


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Line 186: Line 189:
nums.add(null); // allowed   
nums.add(null); // allowed   
</syntaxhighlight>
</syntaxhighlight>
किसी प्रकार के वाइल्डकार्ड के निचले बाउंडिंग वर्ग को निर्दिष्ट करने के लिए, <code>super</code> कीवर्ड का प्रयोग किया जाता है. यह कीवर्ड इंगित करता है कि प्रकार तर्क बाउंडिंग क्लास का एक सुपरटाइप है। इसलिए, {{java|List<? super Number>}} प्रतिनिधित्व कर सकता है <code>List&lt;Number&gt;</code> या <code>List&lt;Object&gt;</code>. परिभाषित सूची से पढ़ना {{java|List<? super Number>}} प्रकार के तत्व लौटाता है <code>Object</code>. ऐसी सूची में जोड़ने के लिए या तो प्रकार के तत्वों की आवश्यकता होती है <code>Number</code>, का कोई भी उपप्रकार <code>Number</code> या शून्य सूचक (जो हर प्रकार का सदस्य है)
किसी प्रकार के वाइल्डकार्ड के निचले बाउंडिंग वर्ग को निर्दिष्ट करने के लिए, <code>super</code> कीवर्ड का प्रयोग किया जाता है। यह कीवर्ड इंगित करता है कि प्रकार तर्क बाउंडिंग क्लास का एक सुपरटाइप है। इसलिए, <code>List&lt;Number&gt;</code> या <code>List&lt;Object&gt;</code> {{java|List<? super Number>}} का प्रतिनिधित्व कर सकता है। {{java|List<?}} के रूप में परिभाषित सूची से पढ़ना <code>super Number></code>  <code>Object</code> प्रकार के तत्व लौटाता है। ऐसी सूची में जोड़ने के लिए या तो <code>Number</code> प्रकार के तत्वों, <code>Number</code> के किसी उपप्रकार या शून्य (जो हर प्रकार का सदस्य है) की आवश्यकता होती है।


[[जोशुआ बलोच]] की पुस्तक इफेक्टिव जावा से स्मरणीय पीईसीएस (निर्माता एक्सटेंड्स, कंज्यूमर सुपर) यह याद रखने का एक आसान तरीका देता है कि जावा में वाइल्डकार्ड (Covariance_and_contravariance_(computer_science) और Covariance और contravariance (कंप्यूटर विज्ञान) के अनुरूप) का उपयोग कब करना है।{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}}
[[जोशुआ बलोच]] की पुस्तक इफेक्टिव जावा से स्मरणीय पीईसीएस (निर्माता एक्सटेंड्स, कंज्यूमर सुपर) यह याद रखने की एक आसान विधि देती है कि जब जावा में वाइल्डकार्ड (सहप्रसरण और विरोधाभास के अनुरूप) का उपयोग करना है।{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}}


==थ्रो क्लॉज़ में जेनरिक ==
==थ्रो क्लॉज़ में जेनरिक ==
हालाँकि अपवाद स्वयं सामान्य नहीं हो सकते, सामान्य पैरामीटर थ्रो क्लॉज में दिखाई दे सकते हैं:
चूँकि अपवाद स्वयं सामान्य नहीं हो सकते, सामान्य पैरामीटर थ्रो क्लॉज में दिखाई दे सकते हैं:


<syntaxhighlight lang="Java">
<syntaxhighlight lang="Java">
Line 203: Line 206:


==प्रकार मिटाने की समस्या==
==प्रकार मिटाने की समस्या==
टाइप-शुद्धता के लिए संकलन-समय पर जेनेरिक की जाँच की जाती है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} सामान्य प्रकार की जानकारी को [[प्रकार मिटाना]] नामक प्रक्रिया में हटा दिया जाता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} उदाहरण के लिए, <code>List&lt;Integer&gt;</code> गैर-जेनेरिक प्रकार में परिवर्तित कर दिया जाएगा <code>List</code>, जिसमें आम तौर पर मनमानी वस्तुएं शामिल होती हैं। संकलन-समय जांच यह गारंटी देती है कि परिणामी कोड सही प्रकार का उपयोग करता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}}
टाइप-शुद्धता के लिए संकलन-समय पर जेनेरिक की जाँच की जाती है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}} सामान्य प्रकार की जानकारी को [[प्रकार मिटाना]] नामक प्रक्रिया में हटा दिया जाता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} उदाहरण के लिए, <code>List&lt;Integer&gt;</code> गैर-जेनेरिक <code>List</code>प्रकार में परिवर्तित कर दिया जाएगा, जिसमें सामान्यतः इच्छानुसार वस्तुएं सम्मिलित होती हैं। संकलन-समय जांच यह गारंटी देती है कि परिणामी कोड सही प्रकार का उपयोग करता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}}


प्रकार मिटाने के कारण, रन-टाइम पर प्रकार पैरामीटर निर्धारित नहीं किए जा सकते।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} उदाहरण के लिए, जब <code>ArrayList</code> रनटाइम पर जांच की जाती है, यह निर्धारित करने का कोई सामान्य तरीका नहीं है कि, प्रकार मिटाने से पहले, यह एक था <code>ArrayList&lt;Integer&gt;</code> या एक <code>ArrayList&lt;Float&gt;</code>. कई लोग इस प्रतिबंध से असंतुष्ट हैं.<ref>{{cite web|first=Neal|last=Gafter|title=जावा के लिए परिष्कृत जेनेरिक|date=2006-11-05|access-date=2010-04-20|url=http://gafter.blogspot.ro/2006/11/reified-generics-for-java.html}}</ref> आंशिक दृष्टिकोण हैं. उदाहरण के लिए, व्यक्तिगत तत्वों की जांच यह निर्धारित करने के लिए की जा सकती है कि वे किस प्रकार के हैं; उदाहरण के लिए, यदि कोई <code>ArrayList</code> एक शामिल है <code>Integer</code>, कि ArrayList को पैरामीटरयुक्त किया गया होगा <code>Integer</code> (हालाँकि, इसे किसी भी माता-पिता के साथ पैरामीटराइज़ किया गया हो सकता है <code>Integer</code>, जैसे कि <code>Number</code> या <code>Object</code>).
 
प्रकार के क्षरण के कारण, रन-टाइम पर प्रकार के पैरामीटर निर्धारित नहीं किए जा सकते।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} उदाहरण के लिए, जब रनटाइम पर एक <code>ArrayList</code> की जांच की जाती है, तो यह निर्धारित करने का कोई सामान्य तरीका नहीं है कि, प्रकार मिटाने से पहले, यह एक <code>ArrayList&lt;Integer&gt;</code> था या एक <code>ArrayList&lt;Float&gt;</code> था। कई लोग इस प्रतिबंध से असंतुष्ट हैं।<ref>{{cite web|first=Neal|last=Gafter|title=जावा के लिए परिष्कृत जेनेरिक|date=2006-11-05|access-date=2010-04-20|url=http://gafter.blogspot.ro/2006/11/reified-generics-for-java.html}}</ref> यह आंशिक दृष्टिकोण हैं। उदाहरण के लिए, व्यक्तिगत तत्वों की जांच यह निर्धारित करने के लिए की जा सकती है कि वे किस प्रकार के हैं; उदाहरण के लिए, यदि किसी <code>ArrayList</code> में एक <code>Integer</code> है, तो उस <code>ArrayList</code> को <code>Integer</code> के साथ पैरामीटराइज़ किया गया हो सकता है (चूँकि, इसे <code>Integer</code> के किसी भी पैरेंट, जैसे <code>Number</code> या <code>Object</code>) के साथ पैरामीटराइज़ किया गया हो सकता है।


इस बिंदु को प्रदर्शित करते हुए, निम्नलिखित कोड समान आउटपुट देता है:
इस बिंदु को प्रदर्शित करते हुए, निम्नलिखित कोड समान आउटपुट देता है:
Line 215: Line 219:
}
}
</syntaxhighlight>
</syntaxhighlight>
प्रकार के क्षरण का एक अन्य प्रभाव यह है कि एक सामान्य वर्ग इसका विस्तार नहीं कर सकता है <code>Throwable</code> कक्षा किसी भी तरह से, प्रत्यक्ष या अप्रत्यक्ष रूप से:<ref>{{cite web|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.2|title=Java Language Specification, Section 8.1.2|publisher=Oracle|access-date=24 October 2015}}</ref>
प्रकार के क्षरण का एक अन्य प्रभाव यह है कि एक सामान्य वर्ग किसी भी तरह से, प्रत्यक्ष या अप्रत्यक्ष रूप से, <code>Throwable</code> वर्ग का विस्तार नहीं कर सकता है:<ref>{{cite web|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.2|title=Java Language Specification, Section 8.1.2|publisher=Oracle|access-date=24 October 2015}}</ref>


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Line 234: Line 238:
टाइप इरेज़र के कारण, रनटाइम को पता नहीं चलेगा कि कौन सा कैच ब्लॉक निष्पादित करना है, इसलिए यह कंपाइलर द्वारा निषिद्ध है।
टाइप इरेज़र के कारण, रनटाइम को पता नहीं चलेगा कि कौन सा कैच ब्लॉक निष्पादित करना है, इसलिए यह कंपाइलर द्वारा निषिद्ध है।


जावा जेनेरिक [[सी++ टेम्पलेट्स]]|C++ टेम्प्लेट से भिन्न हैं। उपयोग किए गए पैरामीटर प्रकारों की संख्या की परवाह किए बिना, जावा जेनेरिक एक जेनेरिक वर्ग या फ़ंक्शन का केवल एक संकलित संस्करण उत्पन्न करते हैं। इसके अलावा, जावा रन-टाइम वातावरण को यह जानने की आवश्यकता नहीं है कि किस पैरामीटरयुक्त प्रकार का उपयोग किया जाता है क्योंकि प्रकार की जानकारी संकलन-समय पर मान्य होती है और संकलित कोड में शामिल नहीं होती है। नतीजतन, एक पैरामीटरयुक्त प्रकार के जावा क्लास को इंस्टेंट करना असंभव है क्योंकि इंस्टेंटेशन के लिए एक कंस्ट्रक्टर को कॉल की आवश्यकता होती है, जो कि प्रकार अज्ञात होने पर अनुपलब्ध है।
जावा जेनेरिक [[सी++ टेम्पलेट्स]] से भिन्न हैं। उपयोग किए गए पैरामीटर प्रकारों की संख्या की परवाह किए बिना, जावा जेनेरिक एक जेनेरिक वर्ग या फलन का केवल एक संकलित संस्करण उत्पन्न करते हैं। इसके अतिरिक्त, जावा रन-टाइम वातावरण को यह जानने की आवश्यकता नहीं है कि किस पैरामीटरयुक्त प्रकार का उपयोग किया जाता है क्योंकि प्रकार की जानकारी संकलन-समय पर मान्य होती है और संकलित कोड में सम्मिलित नहीं होती है। परिणामस्वरूप, एक पैरामीटरयुक्त प्रकार के जावा क्लास को इंस्टेंट करना असंभव है क्योंकि इंस्टेंटेशन के लिए एक कंस्ट्रक्टर को कॉल की आवश्यकता होती है, जो कि प्रकार अज्ञात होने पर अनुपलब्ध है।


उदाहरण के लिए, निम्नलिखित कोड संकलित नहीं किया जा सकता:
उदाहरण के लिए, निम्नलिखित कोड संकलित नहीं किया जा सकता:
Line 242: Line 246:
}
}
</syntaxhighlight>
</syntaxhighlight>
चूँकि रनटाइम पर प्रति जेनेरिक क्लास की केवल एक प्रतिलिपि होती है, [[स्थैतिक चर]] को क्लास के सभी उदाहरणों के बीच साझा किया जाता है, चाहे उनके प्रकार के पैरामीटर कुछ भी हों। नतीजतन, प्रकार पैरामीटर का उपयोग स्थिर चर की घोषणा में या स्थिर तरीकों में नहीं किया जा सकता है।
चूँकि रनटाइम पर प्रति जेनेरिक क्लास की केवल एक प्रतिलिपि होती है, [[स्थैतिक चर]] को क्लास के सभी उदाहरणों के बीच साझा किया जाता है, चाहे उनके प्रकार के पैरामीटर कुछ भी हों। परिणामस्वरूप, प्रकार पैरामीटर का उपयोग स्थिर चर की घोषणा में या स्थिर विधियों में नहीं किया जा सकता है।


जावा SE5 से पहले लिखे गए प्रोग्रामों के साथ बैकवर्ड संगतता बनाए रखने के लिए जावा में टाइप इरेज़र लागू किया गया था।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}}
जावा SE5 से पहले लिखे गए प्रोग्रामों के साथ बैकवर्ड संगतता बनाए रखने के लिए जावा में टाइप इरेज़र प्रयुक्त किया गया था।{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}}


==सरणी से अंतर ==
==सरणी से अंतर ==


सरणियों (आदिम सरणियों और दोनों) के बीच कई महत्वपूर्ण अंतर हैं {{code|Object}} सरणियाँ), और जावा में जेनेरिक। दो प्रमुख अंतर, [[वेरिएंस (कंप्यूटर विज्ञान)]] और [[रीफिकेशन (कंप्यूटर विज्ञान)]] के संदर्भ में अंतर।
जावा में सरणियों (आदिम सरणियों और {{code|Object}} सरणियों दोनों) और जेनेरिक के बीच कई महत्वपूर्ण अंतर हैं। दो प्रमुख अंतर, अर्थात् [[वेरिएंस (कंप्यूटर विज्ञान)|विचरण]] और [[रीफिकेशन (कंप्यूटर विज्ञान)|रीफिकेशन]] के संदर्भ में अंतर।


=== सहप्रसरण, प्रतिप्रसरण और अपरिवर्तन ===
=== सहप्रसरण, प्रतिप्रसरण और अपरिवर्तन ===


{{main article|Covariance and contravariance (computer science)}}
{{main article|सहप्रसरण और प्रतिप्रसरण (कंप्यूटर विज्ञान)}}
जेनेरिक अपरिवर्तनीय हैं, जबकि सरणियाँ सहप्रसरण और प्रतिप्रसरण (कंप्यूटर विज्ञान) हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} सरणियों जैसी गैर-जेनेरिक वस्तुओं की तुलना में जेनेरिक का उपयोग करने का यह एक लाभ है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} विशेष रूप से, जेनरिक डेवलपर को कोड को ठीक करने के लिए मजबूर करने के लिए एक संकलन-समय अपवाद फेंककर रन टाइम अपवादों को रोकने में मदद कर सकता है।
जेनेरिक अपरिवर्तनीय हैं, जबकि सरणियाँ सहप्रसरण और प्रतिप्रसरण (कंप्यूटर विज्ञान) हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} सरणियों जैसी गैर-जेनेरिक वस्तुओं की तुलना में जेनेरिक का उपयोग करने का यह एक लाभ है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} विशेष रूप से, जेनरिक डेवलपर को कोड को ठीक करने के लिए विवश करने के लिए एक संकलन-समय अपवाद फेंककर रन टाइम अपवादों को रोकने में सहायता कर सकता है।


उदाहरण के लिए, यदि कोई डेवलपर घोषित करता है {{code|Object[]}} ऑब्जेक्ट और ऑब्जेक्ट को नए के रूप में त्वरित करता है {{code|Long[]}} ऑब्जेक्ट, कोई संकलन-समय अपवाद नहीं फेंका गया है (चूंकि सरणियाँ सहसंयोजक हैं)।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} इससे यह ग़लत धारणा बन सकती है कि कोड सही ढंग से लिखा गया है। हालाँकि, यदि डेवलपर a जोड़ने का प्रयास करता है {{code|String}} इसके लिये {{code|Long[]}}ऑब्जेक्ट, प्रोग्राम फेंक देगा {{code|ArrayStoreException}}.{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} यदि डेवलपर जेनेरिक का उपयोग करता है तो इस रन-टाइम अपवाद से पूरी तरह बचा जा सकता है।
उदाहरण के लिए, यदि कोई डेवलपर एक {{code|Object[]}} ऑब्जेक्ट घोषित करता है और ऑब्जेक्ट को एक नए {{code|Long[]}}] ऑब्जेक्ट के रूप में इंस्टेंट करता है, तो कोई संकलन-समय अपवाद नहीं फेंका जाता है (क्योंकि एरे सहसंयोजक होते हैं)।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} इससे यह ग़लत धारणा बन सकती है कि कोड सही ढंग से लिखा गया है। चूँकि, यदि डेवलपर इस {{code|Long[]}} ऑब्जेक्ट में एक {{code|String}} जोड़ने का प्रयास करता है, तो प्रोग्राम एक {{code|ArrayStoreException}} फेंक देगा।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} यदि डेवलपर जेनेरिक का उपयोग करता है तो इस रन-टाइम अपवाद से पूरी तरह बचा जा सकता है।


यदि डेवलपर घोषित करता है a {{code|Collection<Object>}} ऑब्जेक्ट रिटर्न प्रकार के साथ इस ऑब्जेक्ट का एक नया उदाहरण बनाता है {{code|ArrayList<Long>}}, जावा कंपाइलर (सही ढंग से) असंगत प्रकारों की उपस्थिति को इंगित करने के लिए एक संकलन-समय अपवाद फेंक देगा (क्योंकि जेनेरिक अपरिवर्तनीय हैं)।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}. इसलिए, यह संभावित रन-टाइम अपवादों से बचा जाता है। का एक उदाहरण बनाकर इस समस्या को ठीक किया जा सकता है {{code|Collection<Object>}} का उपयोग करना {{code|ArrayList<Object>}} इसके बजाय ऑब्जेक्ट करें। जावा SE7 या बाद के संस्करणों का उपयोग करने वाले कोड के लिए, {{code|Collection<Object>}} को एक के साथ त्वरित किया जा सकता है {{code|ArrayList<>}} Java#Diamond_operator में जेनेरिक्स का उपयोग करके ऑब्जेक्ट
यदि डेवलपर एक {{code|Collection<Object>}} ऑब्जेक्ट घोषित करता है और रिटर्न प्रकार {{code|ArrayList<Long>}} के साथ इस ऑब्जेक्ट का एक नया उदाहरण बनाता है, तो जावा कंपाइलर (सही ढंग से) असंगत प्रकारों की उपस्थिति को इंगित करने के लिए एक संकलन-समय अपवाद फेंक देगा (क्योंकि जेनेरिक हैं)।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} इसलिए, यह संभावित रन-टाइम अपवादों से बचा जाता है। इसके बजाय {{code|ArrayList<Object>}} ऑब्जेक्ट का उपयोग करके {{code|Collection<Object>}} का एक उदाहरण बनाकर इस समस्या को ठीक किया जा सकता है। जावा SE7 या बाद के संस्करणों का उपयोग करने वाले कोड के लिए, {{code|Collection<Object>}} को डायमंड ऑपरेटर का उपयोग करके {{code|ArrayList<>}} ऑब्जेक्ट के साथ त्वरित किया जा सकता है।


=== पुनःकरण ===
=== पुनःकरण ===
{{main article|Reification (computer science)}}
{{main article|रीफिकेशन (कंप्यूटर विज्ञान)}}
Arrays Reification (कंप्यूटर विज्ञान) है, जिसका अर्थ है कि एक Array ऑब्जेक्ट रन-टाइम पर अपने प्रकार की जानकारी को लागू करता है, जबकि Java में जेनरिक को Reified नहीं किया जाता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}


अधिक औपचारिक रूप से कहें तो, जावा में सामान्य प्रकार वाली वस्तुएं गैर-शोधन योग्य प्रकार हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} एक गैर-शोधन योग्य प्रकार वह प्रकार है जिसका रन-टाइम पर प्रतिनिधित्व में संकलन-समय पर इसके प्रतिनिधित्व की तुलना में कम जानकारी होती है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}
ऐरे को पुनरीक्षित किया जाता है, जिसका अर्थ है कि एक ऐरे ऑब्जेक्ट रन-टाइम पर अपने प्रकार की जानकारी को प्रयुक्त करता है, जबकि जावा में जेनेरिक को पुन: संशोधित नहीं किया जाता है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}


जावा में सामान्य प्रकार वाली वस्तुएं प्रकार के क्षरण के कारण पुन:शोधन योग्य नहीं होती हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} जावा केवल संकलन-समय पर प्रकार की जानकारी लागू करता है। संकलन-समय पर प्रकार की जानकारी सत्यापित होने के बाद, प्रकार की जानकारी हटा दी जाती है, और रन-टाइम पर, प्रकार की जानकारी उपलब्ध नहीं होगी।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}
अधिक औपचारिक रूप से कहें तो, जावा में सामान्य प्रकार वाली वस्तुएं गैर-शोधन योग्य प्रकार हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} एक गैर-शोधन योग्य प्रकार वह प्रकार है, जिसका रन-टाइम पर प्रतिनिधित्व में संकलन-समय पर इसके प्रतिनिधित्व की तुलना में कम जानकारी होती है।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}


गैर-शोधन योग्य प्रकारों के उदाहरणों में शामिल हैं {{code|List<T>}} और {{code|List<String>}}, कहाँ {{code|T}} एक सामान्य औपचारिक पैरामीटर है। {{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}
जावा में सामान्य प्रकार वाली वस्तुएं प्रकार के क्षरण के कारण पुन:शोधन योग्य नहीं होती हैं।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}} जावा केवल संकलन-समय पर प्रकार की जानकारी प्रयुक्त करता है। संकलन-समय पर प्रकार की जानकारी सत्यापित होने के बाद, प्रकार की जानकारी हटा दी जाती है, और रन-टाइम पर, प्रकार की जानकारी उपलब्ध नहीं होगी।{{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}
 
गैर-शोधन योग्य प्रकारों के उदाहरणों में {{code|List<T>}} और {{code|List<String>}} सम्मिलित हैं, जहाँ {{code|T}} एक सामान्य औपचारिक पैरामीटर है। {{sfn|Bloch|2018|loc=Chapter §5 Item 28: Prefer lists to arrays|pp=126-129}}


==जेनेरिक पर प्रोजेक्ट==
==जेनेरिक पर प्रोजेक्ट==


[[प्रोजेक्ट वल्लाह (जावा भाषा)]] जावा 10 से आगे के संभावित संस्करणों के लिए बेहतर जावा जेनेरिक और भाषा सुविधाओं को विकसित करने के लिए एक प्रायोगिक परियोजना है। संभावित संवर्द्धन में शामिल हैं:<ref>{{cite web|last1=Goetz|first1=Brian|title=वल्लाह में आपका स्वागत है!|url=http://mail.openjdk.java.net/pipermail/valhalla-dev/2014-July/000000.html|website=OpenJDK mail archive|publisher=OpenJDK|access-date=12 August 2014}}</ref>
[[प्रोजेक्ट वल्लाह (जावा भाषा)]] जावा 10 से आगे के संभावित संस्करणों के लिए उत्तम जावा जेनेरिक और भाषा सुविधाओं को विकसित करने के लिए एक प्रायोगिक परियोजना है। संभावित संवर्द्धन में सम्मिलित हैं:<ref>{{cite web|last1=Goetz|first1=Brian|title=वल्लाह में आपका स्वागत है!|url=http://mail.openjdk.java.net/pipermail/valhalla-dev/2014-July/000000.html|website=OpenJDK mail archive|publisher=OpenJDK|access-date=12 August 2014}}</ref>
* सामान्य प्रोग्रामिंग#टेम्पलेट विशेषज्ञता, उदा. सूची<int>
* सामान्य विशेषज्ञता, उदाहरण List<int>
* सी शार्प और जावा#टाइप इरेज़र बनाम रिफाइड जेनेरिक की तुलना; रनटाइम पर वास्तविक प्रकार उपलब्ध कराना।
* रिफाइड जेनेरिक; रनटाइम पर वास्तविक प्रकार उपलब्ध कराना।


==यह भी देखें==
==यह भी देखें==
Line 279: Line 284:
* [[ टेम्प्लेट मेटाप्रोग्रामिंग ]]
* [[ टेम्प्लेट मेटाप्रोग्रामिंग ]]
* वाइल्डकार्ड (जावा)
* वाइल्डकार्ड (जावा)
* सी शार्प और जावा की तुलना|सी# और जावा की तुलना
* सी# और जावा की तुलना
* जावा और सी++ की तुलना
* जावा और सी++ की तुलना


Line 288: Line 293:
==संदर्भ==
==संदर्भ==
*{{cite book | title= "Effective Java: Programming Language Guide" |last=Bloch| first=Joshua| publisher=Addison-Wesley | edition=third | isbn=978-0134685991| year=2018}}
*{{cite book | title= "Effective Java: Programming Language Guide" |last=Bloch| first=Joshua| publisher=Addison-Wesley | edition=third | isbn=978-0134685991| year=2018}}
<!--
[[Category: Machine Translated Page]]
[[Category:Created On 11/07/2023]]

Revision as of 00:52, 18 July 2023

जेनरिक सामान्य प्रोग्रामिंग की एक सुविधा है, जिसे 2004 में जावा प्लेटफ़ॉर्म, मानक संस्करण 5.0 के अन्दर जावा (प्रोग्रामिंग भाषा) में जोड़ा गया था। उन्हें संकलन-समय प्रकार की सुरक्षा प्रदान करते हुए विभिन्न प्रकार की वस्तुओं पर एक प्रकार या विधि को संचालित करने की अनुमति देने के लिए जावा के प्रकार प्रणाली का विस्तार करने के लिए डिज़ाइन किया गया था।[1] पहलू संकलन-समय प्रकार की सुरक्षा पूरी तरह से प्राप्त नहीं की गई थी, क्योंकि 2016 में यह दिखाया गया था कि सभी स्थितियों में इसकी गारंटी नहीं है।[2][3]

जावा संग्रह ढाँचा संग्रह उदाहरण में संग्रहीत वस्तुओं के प्रकार को निर्दिष्ट करने के लिए जेनेरिक का समर्थन करता है।

1998 में, गिलाद ब्राचा, मार्टिन ओडर्सकी , डेविड स्टाउटमायर और फिलिप वाडलर ने जेनेरिक जावा बनाया, जो सामान्य प्रकारों का समर्थन करने के लिए जावा भाषा का एक विस्तार था।[4] जेनेरिक जावा को वाइल्डकार्ड (जावा) के साथ जावा में सम्मिलित किया गया था।

पदानुक्रम और वर्गीकरण

जावा भाषा विशिष्टता के अनुसार:[5]

  • एक प्रकार का चर एक अयोग्य पहचानकर्ता है। प्रकार चर को जेनेरिक क्लास डिक्लेरेशन, जेनेरिक इंटरफ़ेस डिक्लेरेशन, जेनेरिक मेथड डिक्लेरेशन और जेनेरिक कंस्ट्रक्टर डिक्लेरेशन द्वारा प्रस्तुत किया जाता है।
  • एक वर्ग सामान्य है, यदि वह एक या अधिक प्रकार के चर घोषित करता है।[6] यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है, जो पैरामीटर के रूप में कार्य करते हैं।[7] एक सामान्य वर्ग घोषणा पैरामीटरयुक्त प्रकारों के एक सेट को परिभाषित करती है, जो प्रकार पैरामीटर अनुभाग के प्रत्येक संभावित आह्वान के लिए एक है। ये सभी पैरामीटरयुक्त प्रकार रनटाइम पर एक ही क्लास साझा करते हैं।
  • एक इंटरफ़ेस (जावा) सामान्य है यदि यह एक या अधिक प्रकार के चर घोषित करता है।[7] यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है, जो पैरामीटर के रूप में कार्य करते हैं।[7] एक सामान्य इंटरफ़ेस घोषणा प्रकार के एक सेट को परिभाषित करती है, प्रकार पैरामीटर अनुभाग के प्रत्येक संभावित आह्वान के लिए एक। सभी पैरामीटरयुक्त प्रकार रनटाइम पर समान इंटरफ़ेस साझा करते हैं।
  • एक विधि सामान्य है यदि यह एक या अधिक प्रकार के चर घोषित करती है।[8] इस प्रकार के चर को विधि के औपचारिक प्रकार के पैरामीटर के रूप में जाना जाता है। औपचारिक प्रकार पैरामीटर सूची का रूप किसी वर्ग या इंटरफ़ेस के प्रकार पैरामीटर सूची के समान है।
  • एक कंस्ट्रक्टर को जेनेरिक घोषित किया जा सकता है, चाहे कंस्ट्रक्टर को जिस वर्ग में घोषित किया गया है वह स्वयं जेनेरिक है या नहीं। एक कंस्ट्रक्टर सामान्य होता है यदि वह एक या अधिक प्रकार के वेरिएबल घोषित करता है। इन प्रकार के चर को कंस्ट्रक्टर के औपचारिक प्रकार के पैरामीटर के रूप में जाना जाता है। औपचारिक प्रकार पैरामीटर सूची का रूप सामान्य वर्ग या इंटरफ़ेस की प्रकार पैरामीटर सूची के समान है।

प्रेरणा

जावा कोड का निम्नलिखित ब्लॉक उस समस्या को दर्शाता है जो जेनेरिक का उपयोग न करने पर उपलब्ध होती है। सबसे पहले, यह Object प्रकार की ArrayList घोषित करता है। फिर, यह ArrayList में String जोड़ता है। अंत में, यह जोड़े गए String को पुनः प्राप्त करने का प्रयास करता है और इसे Integer में डालने का प्रयास करता है - तर्क में एक त्रुटि, क्योंकि सामान्यतः एक पूर्णांक में इच्छानुसार स्ट्रिंग डालना संभव नहीं है।

final List v = new ArrayList();
v.add("test"); // A String that cannot be cast to an Integer
final Integer i = (Integer) v.get(0); // Run time error

चूँकि कोड बिना किसी त्रुटि के संकलित किया गया है, यह कोड की तीसरी पंक्ति निष्पादित करते समय एक रनटाइम अपवाद (java.lang.ClassCastException) फेंकता है। जेनरिक का उपयोग करके संकलन समय के समय इस प्रकार की तर्क त्रुटि का पता लगाया जा सकता है[7] और उनका उपयोग करने के लिए प्राथमिक प्रेरणा है।[6] यह एक या अधिक प्रकार के वेरिएबल को परिभाषित करता है, जो पैरामीटर के रूप में कार्य करते हैं।

उपरोक्त कोड खंड को जेनेरिक का उपयोग करके निम्नानुसार फिर से लिखा जा सकता है:

final List<String> v = new ArrayList<String>();
v.add("test");
final Integer i = (Integer) v.get(0); // (type error)  compilation-time error

कोण कोष्ठक के अन्दर टाइप पैरामीटर String ArrayList को String (ArrayList के सामान्य Object घटकों का वंशज) से गठित होने की घोषणा करता है। जेनेरिक के साथ, तीसरी पंक्ति को किसी विशेष प्रकार में डालना अब आवश्यक नहीं है, क्योंकि v.get(0) के परिणाम को कंपाइलर द्वारा उत्पन्न कोड द्वारा String के रूप में परिभाषित किया गया है।

इस खंड की तीसरी पंक्ति में तार्किक दोष को संकलन-समय त्रुटि (J2SE 5.0 या बाद के संस्करण के साथ) के रूप में पहचाना जाएगा क्योंकि कंपाइलर यह पता लगाएगा कि v.get(0) Integer पूर्णांक के अतिरिक्त String लौटाता है।[7] अधिक विस्तृत उदाहरण के लिए, संदर्भ देखें।[9]

यहां पैकेज java.util में इंटरफेस java.util.List और java.util.Iterator की परिभाषा से एक छोटा सा अंश दिया गया है:

interface List<E> { 

    void add(E x);
    Iterator<E> iterator();

}

interface Iterator<E> {

    E next();
    boolean hasNext();

}


सामान्य वर्ग परिभाषाएँ

यहां एक सामान्य जावा क्लास का उदाहरण दिया गया है, जिसका उपयोग मानचित्र (कंप्यूटर विज्ञान) में व्यक्तिगत प्रविष्टियों (वैल्यू मैपिंग की कुंजी) को दर्शाने के लिए किया जा सकता है:

public class Entry<KeyType, ValueType> {
  
    private final KeyType key;
    private final ValueType value;

    public Entry(KeyType key, ValueType value) {  
        this.key = key;
        this.value = value;
    }

    public KeyType getKey() {
        return key;
    }

    public ValueType getValue() {
        return value;
    }

    public String toString() { 
        return "(" + key + ", " + value + ")";  
    }

}

इस सामान्य वर्ग का उपयोग निम्नलिखित विधियों से किया जा सकता है, उदाहरण के लिए:

final Entry<String, String> grade = new Entry<String, String>("Mike", "A");
final Entry<String, Integer> mark = new Entry<String, Integer>("Mike", 100);
System.out.println("grade: " + grade);
System.out.println("mark: " + mark);

final Entry<Integer, Boolean> prime = new Entry<Integer, Boolean>(13, true);
if (prime.getValue()) {
    System.out.println(prime.getKey() + " is prime.");
}
else {
    System.out.println(prime.getKey() + " is not prime.");
}

यह आउटपुट देता है:

grade: (Mike, A)
mark: (Mike, 100)
13 is prime.

सामान्य विधि परिभाषाएँ

उपरोक्त सामान्य वर्ग का उपयोग करते हुए एक सामान्य विधि का उदाहरण यहां दिया गया है:

public static <Type> Entry<Type, Type> twice(Type value) {
    return new Entry<Type, Type>(value, value);
}

नोट: यदि हम पहले <Type> को हटा दें, उपरोक्त विधि में, हमें संकलन त्रुटि मिलेगी (प्रतीक प्रकार नहीं मिल सका), क्योंकि यह प्रतीक की घोषणा का प्रतिनिधित्व करता है।

कई स्थितियों में, विधि के उपयोगकर्ता को प्रकार के मापदंडों को इंगित करने की आवश्यकता नहीं होती है, क्योंकि उनका अनुमान लगाया जा सकता है:

final Entry<String, String> pair = Entry.twice("Hello");

यदि आवश्यक हो तो पैरामीटर स्पष्ट रूप से जोड़े जा सकते हैं:

final Entry<String, String> pair = Entry.<String>twice("Hello");

आदिम प्रकार के उपयोग की अनुमति नहीं है, और इसके अतिरिक्त ऑब्जेक्ट प्रकार (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) बॉक्सिंग संस्करणों का उपयोग किया जाना चाहिए:

final Entry<int, int> pair; // Fails compilation. Use Integer instead.

दिए गए मापदंडों के आधार पर सामान्य विधि बनाने की भी संभावना है।

public <Type> Type[] toArray(Type... elements) {
    return elements;
}

ऐसी स्थितियों में आप आदिम प्रकारों का भी उपयोग नहीं कर सकते, उदाहरण के लिए:

Integer[] array = toArray(1, 2, 3, 4, 5, 6);


डायमंड ऑपरेटर

प्रकार के अनुमान के लिए धन्यवाद, जावा एसई 7 और इसके बाद के संस्करण प्रोग्रामर को कोण कोष्ठक की एक खाली जोड़ी (<>, जिसे डायमंड ऑपरेटर कहा जाता है) को कोण कोष्ठक की एक जोड़ी के लिए प्रतिस्थापित करने की अनुमति देता है जिसमें एक या अधिक प्रकार के पैरामीटर होते हैं जो पर्याप्त रूप से बंद संदर्भ का तात्पर्य है।[10] इस प्रकार, Entry का उपयोग करके उपरोक्त कोड उदाहरण को इस प्रकार पुनः लिखा जा सकता है:

final Entry<String, String> grade = new Entry<>("Mike", "A");
final Entry<String, Integer> mark = new Entry<>("Mike", 100);
System.out.println("grade: " + grade);
System.out.println("mark: " + mark);

final Entry<Integer, Boolean> prime = new Entry<>(13, true);
if (prime.getValue()) System.out.println(prime.getKey() + " is prime.");
else System.out.println(prime.getKey() + " is not prime.");


वाइल्डकार्ड टाइप करें

पैरामीटरयुक्त प्रकार के लिए एक प्रकार का तर्क किसी ठोस वर्ग या इंटरफ़ेस तक सीमित नहीं है। जावा पैरामीटरयुक्त प्रकारों के लिए प्रकार के तर्क के रूप में "टाइप वाइल्डकार्ड" के उपयोग की अनुमति देता है। वाइल्डकार्ड "<?>" रूप में प्रकार के तर्क हैं; वैकल्पिक रूप से ऊपरी या निचली सीमा के साथ। यह देखते हुए कि वाइल्डकार्ड द्वारा दर्शाया गया स्पष्ट प्रकार अज्ञात है, उन विधियों के प्रकार पर प्रतिबंध लगाए जाते हैं जिन्हें किसी ऑब्जेक्ट पर बुलाया जा सकता है जो पैरामीटरयुक्त प्रकारों का उपयोग करता है।

यहां एक उदाहरण दिया गया है जहां Collection<E> के तत्व प्रकार को वाइल्डकार्ड द्वारा पैरामीटराइज़ किया गया है:

final Collection<?> c = new ArrayList<String>();
c.add(new Object()); // compile-time error
c.add(null); // allowed

चूँकि हम नहीं जानते कि तत्व प्रकार c का क्या अर्थ है, हम इसमें ऑब्जेक्ट नहीं जोड़ सकते। add() विधि E e> प्रकार के तर्क लेती है, जो कि Collection<E> जेनेरिक इंटरफ़ेस का तत्व प्रकार है। जब वास्तविक प्रकार का तर्क ? होता है, तो यह किसी अज्ञात प्रकार का प्रतिनिधित्व करता है। add() विधि में हम जो भी विधि तर्क मान पास करते हैं वह इस अज्ञात प्रकार का उपप्रकार होना चाहिए। चूँकि हम नहीं जानते कि वह किस प्रकार का है, हम कुछ भी पारित नहीं कर सकते हैं। एकमात्र अपवाद शून्य है; जो हर प्रकार का सदस्य है।[11]

किसी प्रकार के वाइल्डकार्ड की ऊपरी सीमा को निर्दिष्ट करने के लिए, extends कीवर्ड का उपयोग यह इंगित करने के लिए किया जाता है कि प्रकार तर्क बाउंडिंग क्लास का एक उपप्रकार है।[12] तो List<? extends Number> का अर्थ है कि दी गई सूची में कुछ अज्ञात प्रकार की वस्तुएं हैं जो Number वर्ग का विस्तार करती हैं। उदाहरण के लिए, सूची List<Float> या List<Number> हो सकती है। सूची से किसी तत्व को पढ़ने पर एक Number वापस आ जाएगी। फिर से, अशक्त तत्वों को जोड़ने की भी अनुमति है।[13]

उपरोक्त वाइल्डकार्ड का उपयोग लचीलापन जोड़ता है[12] क्योंकि ठोस प्रकार के तर्क के साथ किन्हीं दो पैरामीटरयुक्त प्रकारों के बीच कोई विरासत संबंध नहीं है। न तो List<Number> और न ही List<Integer> दूसरे का उपप्रकार है; तथापि Integer Number का एक उपप्रकार है।[12] इसलिए, कोई भी विधि जो List<Number> को एक पैरामीटर के रूप में लेती है, List<Integer> के तर्क को स्वीकार नहीं करती है। यदि ऐसा होता, तो इसमें एक ऐसा Number सम्मिलित करना संभव होता जो Integer नहीं है; जो प्रकार की सुरक्षा का उल्लंघन करता है। यहां एक उदाहरण दिया गया है जो दर्शाता है कि यदि List<Integer> List<Number> का एक उपप्रकार होता तो किस प्रकार प्रकार की सुरक्षा का उल्लंघन किया जाता:

final List<Integer> ints = new ArrayList<>();
ints.add(2);
final List<Number> nums = ints;  // valid if List<Integer> were a subtype of List<Number> according to substitution rule. 
nums.add(3.14);  
final Integer x = ints.get(1); // now 3.14 is assigned to an Integer variable!

वाइल्डकार्ड के साथ समाधान काम करता है क्योंकि यह उन परिचालनों की अनुमति नहीं देता है जो प्रकार की सुरक्षा का उल्लंघन करेंगे:

final List<? extends Number> nums = ints;  // OK
nums.add(3.14); // compile-time error
nums.add(null); // allowed

किसी प्रकार के वाइल्डकार्ड के निचले बाउंडिंग वर्ग को निर्दिष्ट करने के लिए, super कीवर्ड का प्रयोग किया जाता है। यह कीवर्ड इंगित करता है कि प्रकार तर्क बाउंडिंग क्लास का एक सुपरटाइप है। इसलिए, List<Number> या List<Object> List<? super Number> का प्रतिनिधित्व कर सकता है। List<? के रूप में परिभाषित सूची से पढ़ना super Number> Object प्रकार के तत्व लौटाता है। ऐसी सूची में जोड़ने के लिए या तो Number प्रकार के तत्वों, Number के किसी उपप्रकार या शून्य (जो हर प्रकार का सदस्य है) की आवश्यकता होती है।

जोशुआ बलोच की पुस्तक इफेक्टिव जावा से स्मरणीय पीईसीएस (निर्माता एक्सटेंड्स, कंज्यूमर सुपर) यह याद रखने की एक आसान विधि देती है कि जब जावा में वाइल्डकार्ड (सहप्रसरण और विरोधाभास के अनुरूप) का उपयोग करना है।[12]

थ्रो क्लॉज़ में जेनरिक

चूँकि अपवाद स्वयं सामान्य नहीं हो सकते, सामान्य पैरामीटर थ्रो क्लॉज में दिखाई दे सकते हैं:

public <T extends Throwable> void throwMeConditional(boolean conditional, T exception) throws T {
    if (conditional) {
        throw exception;
    }
}


प्रकार मिटाने की समस्या

टाइप-शुद्धता के लिए संकलन-समय पर जेनेरिक की जाँच की जाती है।[7] सामान्य प्रकार की जानकारी को प्रकार मिटाना नामक प्रक्रिया में हटा दिया जाता है।[6] उदाहरण के लिए, List<Integer> गैर-जेनेरिक Listप्रकार में परिवर्तित कर दिया जाएगा, जिसमें सामान्यतः इच्छानुसार वस्तुएं सम्मिलित होती हैं। संकलन-समय जांच यह गारंटी देती है कि परिणामी कोड सही प्रकार का उपयोग करता है।[7]


प्रकार के क्षरण के कारण, रन-टाइम पर प्रकार के पैरामीटर निर्धारित नहीं किए जा सकते।[6] उदाहरण के लिए, जब रनटाइम पर एक ArrayList की जांच की जाती है, तो यह निर्धारित करने का कोई सामान्य तरीका नहीं है कि, प्रकार मिटाने से पहले, यह एक ArrayList<Integer> था या एक ArrayList<Float> था। कई लोग इस प्रतिबंध से असंतुष्ट हैं।[14] यह आंशिक दृष्टिकोण हैं। उदाहरण के लिए, व्यक्तिगत तत्वों की जांच यह निर्धारित करने के लिए की जा सकती है कि वे किस प्रकार के हैं; उदाहरण के लिए, यदि किसी ArrayList में एक Integer है, तो उस ArrayList को Integer के साथ पैरामीटराइज़ किया गया हो सकता है (चूँकि, इसे Integer के किसी भी पैरेंट, जैसे Number या Object) के साथ पैरामीटराइज़ किया गया हो सकता है।

इस बिंदु को प्रदर्शित करते हुए, निम्नलिखित कोड समान आउटपुट देता है:

final List<Integer> li = new ArrayList<>();
final List<Float> lf = new ArrayList<>();
if (li.getClass() == lf.getClass()) { // evaluates to true
    System.out.println("Equal");
}

प्रकार के क्षरण का एक अन्य प्रभाव यह है कि एक सामान्य वर्ग किसी भी तरह से, प्रत्यक्ष या अप्रत्यक्ष रूप से, Throwable वर्ग का विस्तार नहीं कर सकता है:[15]

public class GenericException<T> extends Exception

इसके समर्थित न होने का कारण प्रकार का क्षरण है:

try {
    throw new GenericException<Integer>();
}
catch (GenericException<Integer> e) {
    System.err.println("Integer");
}
catch (GenericException<String> e) {
    System.err.println("String");
}

टाइप इरेज़र के कारण, रनटाइम को पता नहीं चलेगा कि कौन सा कैच ब्लॉक निष्पादित करना है, इसलिए यह कंपाइलर द्वारा निषिद्ध है।

जावा जेनेरिक सी++ टेम्पलेट्स से भिन्न हैं। उपयोग किए गए पैरामीटर प्रकारों की संख्या की परवाह किए बिना, जावा जेनेरिक एक जेनेरिक वर्ग या फलन का केवल एक संकलित संस्करण उत्पन्न करते हैं। इसके अतिरिक्त, जावा रन-टाइम वातावरण को यह जानने की आवश्यकता नहीं है कि किस पैरामीटरयुक्त प्रकार का उपयोग किया जाता है क्योंकि प्रकार की जानकारी संकलन-समय पर मान्य होती है और संकलित कोड में सम्मिलित नहीं होती है। परिणामस्वरूप, एक पैरामीटरयुक्त प्रकार के जावा क्लास को इंस्टेंट करना असंभव है क्योंकि इंस्टेंटेशन के लिए एक कंस्ट्रक्टर को कॉल की आवश्यकता होती है, जो कि प्रकार अज्ञात होने पर अनुपलब्ध है।

उदाहरण के लिए, निम्नलिखित कोड संकलित नहीं किया जा सकता:

<T> T instantiateElementType(List<T> arg) {
     return new T(); //causes a compile error
}

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

जावा SE5 से पहले लिखे गए प्रोग्रामों के साथ बैकवर्ड संगतता बनाए रखने के लिए जावा में टाइप इरेज़र प्रयुक्त किया गया था।[7]

सरणी से अंतर

जावा में सरणियों (आदिम सरणियों और Object सरणियों दोनों) और जेनेरिक के बीच कई महत्वपूर्ण अंतर हैं। दो प्रमुख अंतर, अर्थात् विचरण और रीफिकेशन के संदर्भ में अंतर।

सहप्रसरण, प्रतिप्रसरण और अपरिवर्तन

जेनेरिक अपरिवर्तनीय हैं, जबकि सरणियाँ सहप्रसरण और प्रतिप्रसरण (कंप्यूटर विज्ञान) हैं।[6] सरणियों जैसी गैर-जेनेरिक वस्तुओं की तुलना में जेनेरिक का उपयोग करने का यह एक लाभ है।[6] विशेष रूप से, जेनरिक डेवलपर को कोड को ठीक करने के लिए विवश करने के लिए एक संकलन-समय अपवाद फेंककर रन टाइम अपवादों को रोकने में सहायता कर सकता है।

उदाहरण के लिए, यदि कोई डेवलपर एक Object[] ऑब्जेक्ट घोषित करता है और ऑब्जेक्ट को एक नए Long[]] ऑब्जेक्ट के रूप में इंस्टेंट करता है, तो कोई संकलन-समय अपवाद नहीं फेंका जाता है (क्योंकि एरे सहसंयोजक होते हैं)।[6] इससे यह ग़लत धारणा बन सकती है कि कोड सही ढंग से लिखा गया है। चूँकि, यदि डेवलपर इस Long[] ऑब्जेक्ट में एक String जोड़ने का प्रयास करता है, तो प्रोग्राम एक ArrayStoreException फेंक देगा।[6] यदि डेवलपर जेनेरिक का उपयोग करता है तो इस रन-टाइम अपवाद से पूरी तरह बचा जा सकता है।

यदि डेवलपर एक Collection<Object> ऑब्जेक्ट घोषित करता है और रिटर्न प्रकार ArrayList<Long> के साथ इस ऑब्जेक्ट का एक नया उदाहरण बनाता है, तो जावा कंपाइलर (सही ढंग से) असंगत प्रकारों की उपस्थिति को इंगित करने के लिए एक संकलन-समय अपवाद फेंक देगा (क्योंकि जेनेरिक हैं)।[6] इसलिए, यह संभावित रन-टाइम अपवादों से बचा जाता है। इसके बजाय ArrayList<Object> ऑब्जेक्ट का उपयोग करके Collection<Object> का एक उदाहरण बनाकर इस समस्या को ठीक किया जा सकता है। जावा SE7 या बाद के संस्करणों का उपयोग करने वाले कोड के लिए, Collection<Object> को डायमंड ऑपरेटर का उपयोग करके ArrayList<> ऑब्जेक्ट के साथ त्वरित किया जा सकता है।

पुनःकरण

ऐरे को पुनरीक्षित किया जाता है, जिसका अर्थ है कि एक ऐरे ऑब्जेक्ट रन-टाइम पर अपने प्रकार की जानकारी को प्रयुक्त करता है, जबकि जावा में जेनेरिक को पुन: संशोधित नहीं किया जाता है।[6]

अधिक औपचारिक रूप से कहें तो, जावा में सामान्य प्रकार वाली वस्तुएं गैर-शोधन योग्य प्रकार हैं।[6] एक गैर-शोधन योग्य प्रकार वह प्रकार है, जिसका रन-टाइम पर प्रतिनिधित्व में संकलन-समय पर इसके प्रतिनिधित्व की तुलना में कम जानकारी होती है।[6]

जावा में सामान्य प्रकार वाली वस्तुएं प्रकार के क्षरण के कारण पुन:शोधन योग्य नहीं होती हैं।[6] जावा केवल संकलन-समय पर प्रकार की जानकारी प्रयुक्त करता है। संकलन-समय पर प्रकार की जानकारी सत्यापित होने के बाद, प्रकार की जानकारी हटा दी जाती है, और रन-टाइम पर, प्रकार की जानकारी उपलब्ध नहीं होगी।[6]

गैर-शोधन योग्य प्रकारों के उदाहरणों में List<T> और List<String> सम्मिलित हैं, जहाँ T एक सामान्य औपचारिक पैरामीटर है। [6]

जेनेरिक पर प्रोजेक्ट

प्रोजेक्ट वल्लाह (जावा भाषा) जावा 10 से आगे के संभावित संस्करणों के लिए उत्तम जावा जेनेरिक और भाषा सुविधाओं को विकसित करने के लिए एक प्रायोगिक परियोजना है। संभावित संवर्द्धन में सम्मिलित हैं:[16]

  • सामान्य विशेषज्ञता, उदाहरण List<int>
  • रिफाइड जेनेरिक; रनटाइम पर वास्तविक प्रकार उपलब्ध कराना।

यह भी देखें

उद्धरण

  1. Java Programming Language
  2. A ClassCastException can be thrown even in the absence of casts or nulls."Java and Scala's Type Systems are Unsound" (PDF).
  3. Bloch 2018, pp. 123–125, Chapter §5 Item 27: Eliminate unchecked warnings.
  4. GJ: Generic Java
  5. Java Language Specification, Third Edition by James Gosling, Bill Joy, Guy Steele, Gilad Bracha – Prentice Hall PTR 2005
  6. 6.00 6.01 6.02 6.03 6.04 6.05 6.06 6.07 6.08 6.09 6.10 6.11 6.12 6.13 6.14 Bloch 2018, pp. 126–129, Chapter §5 Item 28: Prefer lists to arrays.
  7. 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 Bloch 2018, pp. 117–122, Chapter §5 Item 26: Don't use raw types.
  8. Bloch 2018, pp. 135–138, Chapter §5 Item 30: Favor generic methods.
  9. Gilad Bracha (July 5, 2004). "जावा प्रोग्रामिंग भाषा में जेनेरिक" (PDF). www.oracle.com.
  10. "Type Inference for Generic Instance Creation".
  11. Gilad Bracha (July 5, 2004). "जावा प्रोग्रामिंग भाषा में जेनेरिक" (PDF). www.oracle.com. p. 5.
  12. 12.0 12.1 12.2 12.3 Bloch 2018, pp. 139–145, Chapter §5 Item 31: Use bounded wildcards to increase API flexibility.
  13. Bracha, Gilad. "Wildcards > Bonus > Generics". The Java™ Tutorials. Oracle. ...The sole exception is null, which is a member of every type...
  14. Gafter, Neal (2006-11-05). "जावा के लिए परिष्कृत जेनेरिक". Retrieved 2010-04-20.
  15. "Java Language Specification, Section 8.1.2". Oracle. Retrieved 24 October 2015.
  16. Goetz, Brian. "वल्लाह में आपका स्वागत है!". OpenJDK mail archive. OpenJDK. Retrieved 12 August 2014.


संदर्भ

  • Bloch, Joshua (2018). "Effective Java: Programming Language Guide" (third ed.). Addison-Wesley. ISBN 978-0134685991.