इसके पीछे के मुख्य कारण को समझने के लिए कुछ संदर्भ की आवश्यकता होती है।
आदिम बनाम वर्ग
जावा में आदिम चर में मान (एक पूर्णांक, एक डबल-सटीक फ़्लोटिंग पॉइंट बाइनरी नंबर, आदि) होते हैं। क्योंकि इन मानों की अलग-अलग लंबाई हो सकती है , उनके वाले चर भी अलग-अलग लंबाई (विचार float
बनाम) हो सकते हैंdouble
) हो सकते हैं।
दूसरी ओर, वर्ग चर में उदाहरणों के संदर्भ होते हैं । संदर्भ आमतौर पर कई भाषाओं में संकेत (या कुछ बहुत समान बिंदुओं के समान) के रूप में कार्यान्वित किए जाते हैं। ये चीजें आम तौर पर एक ही आकार की होती हैं, चाहे वे उदाहरणों के आकार की परवाह किए बिना हों Object
, ( String
,Integer
, आदि)।
वर्ग चर की यह संपत्ति उन संदर्भों को बनाती है जिनमें वे विनिमेय होते हैं (एक हद तक)। यह हमें वह करने की अनुमति देता है जिसे हम प्रतिस्थापन कहते हैं : मोटे तौर पर किसी अन्य प्रकार के उदाहरण के रूप में, संबंधित प्रकार के उपयोग के लिए (एक के String
रूप में उपयोग करें)Object
उदाहरण के लिए, )।
आदिम चर एक ही तरह से विनिमेय नहीं हैं , न तो एक दूसरे के साथ, न ही साथObject
। इसका सबसे स्पष्ट कारण (लेकिन एकमात्र कारण नहीं) उनके आकार का अंतर है। यह इस संबंध में आदिम प्रकार को असुविधाजनक बनाता है, लेकिन हमें अभी भी भाषा में उनकी आवश्यकता है (उन कारणों के लिए जो मुख्य रूप से प्रदर्शन के लिए उबालते हैं)।
जेनरिक और टाइप इरेज़र
जेनेरिक प्रकार एक या अधिक प्रकार के मापदंडों के साथ प्रकार होते हैं (सटीक संख्या को जेनेरिक एरिटी कहा जाता है )। उदाहरण के लिए, जेनेरिक प्रकार की परिभाषा List<T>
में एक प्रकार का पैरामीटर होता है T
, जो हो सकता है Object
(एक ठोस प्रकार का निर्माण List<Object>
), String
( List<String>
), Integer
( )List<Integer>
) और इसी तरह हो सकता है।
जेनेरिक प्रकार गैर-सामान्य लोगों की तुलना में बहुत अधिक जटिल हैं। जब उन्हें जावा (इसकी प्रारंभिक रिलीज़ के बाद) में पेश किया गया था, तो जेवीएम में मौलिक परिवर्तन करने और संभवतः पुराने बायनेरिज़ के साथ संगतता को तोड़ने से बचने के लिए, जावा के रचनाकारों ने जेनेरिक प्रकारों को कम से कम आक्रामक तरीके से लागू करने का फैसला किया: सभी ठोस प्रकार List<T>
वास्तव में, (बाइनरी समतुल्य) के लिए संकलित ( List<Object>
अन्य प्रकारों के लिए, बाउंड कुछ और के अलावा हो सकता है Object
, लेकिन आपको बिंदु मिलता है)। सामान्य प्रक्रिया और प्रकार की पैरामीटर जानकारी इस प्रक्रिया में खो जाती है, यही कारण है कि हम इसे प्रकार का क्षरण कहते हैं ।
दोनों को एक साथ रखना
अब समस्या उपरोक्त वास्तविकताओं का संयोजन है: यदि सभी मामलों में List<T>
हो जाता List<Object>
है, तो T
हमेशा एक प्रकार होना चाहिए जिसे सीधे सौंपा जा सकता हैObject
। किसी और चीज की अनुमति नहीं दी जा सकती। के बाद से, के रूप में हम ने कहा कि इससे पहले कि, int
, float
और double
साथ परस्पर विनिमय नहीं कर रहे हैं Object
, वहाँ नहीं एक हो सकता है List<int>
, List<float>
याList<double>
(जब तक कि जेनरिक के एक काफी अधिक जटिल कार्यान्वयन JVM में ही अस्तित्व में)।
लेकिन जावा प्रकारों की पेशकश करता है Integer
, Float
और Double
जो इन प्राथमिकताओं को वर्ग उदाहरणों में लपेटते हैं, जिससे उन्हें प्रभावी रूप से प्रतिस्थापित किया जा सकता है Object
, इस प्रकार जेनेरिक प्रकारों को अप्रत्यक्ष रूप से साथ ही साथ काम करने की अनुमति मिलती है (क्योंकि आपके पास हो सकता है List<Integer>
, List<Float>
)List<Double>
और इतने पर)।
A , a, from a आदि Integer
से बनाने की प्रक्रिया को बॉक्सिंग कहा जाता है । रिवर्स को अनबॉक्सिंग कहा जाता है । क्योंकि हर बार जब आप उन्हें उपयोग करना चाहते हैं, तो बॉक्स प्राइमेटिव्स असुविधाजनक होने के बावजूद , ऐसे मामले हैं जहां भाषा स्वचालित रूप से ऐसा करती है - जिसे ऑटोबॉक्सिंग कहा जाता है ।int
Float
float
Object