जावा 6 बनाम जावा 7 के बीच ऑटो-अनबॉक्सिंग में अंतर


107

मैंने जावा एसई 6 और जावा एसई 7 के बीच ऑटो अनबॉक्सिंग व्यवहार में अंतर देखा है। मैं सोच रहा हूं कि ऐसा क्यों है, क्योंकि मैं इन दो संस्करणों के बीच इस व्यवहार में बदलाव का कोई दस्तावेज नहीं पा सकता हूं।

यहाँ एक सरल उदाहरण दिया गया है:

Object[] objs = new Object[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];

यह जावा एसई 7 से जेवैक के साथ ठीक संकलित करता है। हालांकि, यदि मैं कंपाइलर को "-source 1.6" तर्क देता हूं तो मुझे अंतिम पंक्ति में एक त्रुटि मिलती है:

inconvertible types
found   : java.lang.Object
required: int

मैंने देशी संस्करण 6 संकलक (बिना किसी स्रोत विकल्प) के संकलन के लिए जावा एसई 6 डाउनलोड करने की कोशिश की। यह सहमत है और ऊपर के रूप में एक ही त्रुटि देता है।

तो क्या देता है? कुछ और प्रयोग से ऐसा लगता है कि जावा 6 में अनबॉक्सिंग केवल उन्बॉक्स मानों को हटा सकता है जो स्पष्ट रूप से (संकलन के समय) बॉक्सिंग प्रकार के हैं। उदाहरण के लिए, यह दोनों संस्करणों में काम करता है:

Integer[] objs = new Integer[2];
objs[0] = new Integer(5);
int myInt = (int)objs[0];

तो ऐसा लगता है कि जावा 6 और 7 के बीच, अनबॉक्सिंग सुविधा को बढ़ाया गया था ताकि वह एक झपट्टा में वस्तु प्रकारों को कच्चा और अनबॉक्स कर सके, बिना यह जाने (संकलन के समय) कि मूल्य उचित बॉक्सिंग प्रकार का है। हालाँकि, जावा भाषा विनिर्देश या ब्लॉग पोस्टिंग के माध्यम से पढ़ना, जो उस समय जावा 7 में लिखा गया था, मैं इस चीज़ का कोई भी बदलाव नहीं देख सकता, इसलिए मैं सोच रहा हूँ कि परिवर्तन क्या है और इस "फीचर" को क्या कहा जाता है ?

बस एक जिज्ञासा: परिवर्तन के कारण, "गलत" अनबॉक्सिंग को ट्रिगर करना संभव है:

Object[] objs = new Float[2];
objs[0] = new Float(5);
int myInt = (int)objs[0];

यह ठीक संकलित करता है, लेकिन रनटाइम पर एक ClassCastException देता है।

इस पर कोई संदर्भ?


17
दिलचस्प। ऑटोबॉक्सिंग गड़बड़ के लिए एक नया घटक। मुझे लगता है कि आपका उदाहरण एक सरणी के बजाय किसी एकल ऑब्जेक्ट के साथ अधिक सरल और स्पष्ट हो सकता है। Integer obj = new Integer(2); int x = (int)obj;: जावा 7 पर काम करता है, जावा 6. पर त्रुटि देता है
leonbloy

1
आप किस JDK का उपयोग कर रहे हैं? यह भी विभिन्न विक्रेताओं के साथ करना पड़ सकता है ...
बारफूइन

1
@leonbloy: सरलीकरण के बारे में अच्छी बात, मैंने इसे कुछ हद तक सरल किया (अपने मूल कोड से) लेकिन किसी तरह बहुत जल्दी रोक दिया!
मर्टी

@ थोमस: यह ओरेकल का नवीनतम JDK (प्रत्येक संस्करण के लिए) था जिसका मैंने उपयोग किया था।
मर्टी

2
ऑटोबॉक्सिंग का कभी उपयोग न करने का एक और कारण।
ग्यारग्यभराम

जवाबों:


92

ऐसा लगता है कि जावा 7 JLS की धारा 5.5 कास्टिंग रूपांतरण में भाषा जावा 5/6 JLS में एक ही अनुभाग की तुलना में अपडेट की गई थी , संभवतः अनुमत रूपांतरणों को स्पष्ट करने के लिए।

जावा 7 जेएलएस का कहना है

एक संदर्भ प्रकार की एक अभिव्यक्ति त्रुटि के बिना एक आदिम प्रकार के रूपांतरण को अंडरबॉक्सिंग के माध्यम से कास्टिंग रूपांतरण से गुजर सकती है।

जावा 5/6:

एक संदर्भ प्रकार का मान अनबॉक्सिंग रूपांतरण (a5.1.8) द्वारा एक आदिम प्रकार के लिए डाला जा सकता है।

जावा 7 जेएलएस में अनुमत रूपांतरणों की एक तालिका (तालिका 5.1) भी है (यह तालिका जावा 5/6 जेएलएस में शामिल नहीं है) संदर्भ प्रकारों से आदिम तक। यह स्पष्ट रूप से वस्तुनिष्ठ से रूपांतरण के रूप में एक संदर्भ संदर्भ रूपांतरण के रूप में ऑब्जेक्ट से प्रिमिटिव तक जाती को सूचीबद्ध करता है।

इस ईमेल में इसका कारण बताया गया है :

निचला रेखा: यदि कल्पना। अनुमति (ऑब्जेक्ट) (int) यह भी अनुमति देनी चाहिए (int) (ऑब्जेक्ट)।


35

तुम सही हो; इसे और अधिक सीधे शब्दों में कहें:

Object o = new Integer(1234);
int x = (int) o;

यह जावा 7 में काम करता है, लेकिन जावा 6 और नीचे में संकलन त्रुटि देता है। अजीब बात है, इस सुविधा को प्रमुखता से प्रलेखित नहीं किया गया है; उदाहरण के लिए, यह यहाँ उल्लेख नहीं है । यदि यह एक नई सुविधा या बग फिक्स (या एक नया बग?) है, तो कुछ संबंधित जानकारी और चर्चा देखें । सर्वसम्मति मूल कल्पना में एक अस्पष्टता की ओर इशारा करती है , जिसके कारण जावा 5/6 पर थोड़ा गलत / असंगत कार्यान्वयन हुआ, जो 7 में तय किया गया था, क्योंकि यह JSR 292 (डायनामिक रूप से विशिष्ट भाषा) के कार्यान्वयन के लिए महत्वपूर्ण था।

जावा ऑटोबॉक्सिंग में अब कुछ और जाल और आश्चर्य है। उदाहरण के लिए

Object obj = new Integer(1234);
long x = (long)obj;

संकलन करेगा, लेकिन ClassCastExceptionरनटाइम में विफल (साथ )। इसके बजाय, यह काम करेगा:

long x = (long)(int)obj;


2
जवाब के लिए धन्यवाद। हालाँकि, एक बात है जो मुझे समझ नहीं आ रही है। यह JLS और उसके साथ कार्यान्वयन (cf. मेल चर्चा) के साथ एक स्पष्टीकरण है, लेकिन JVM पर अन्य टाइप की गई भाषाओं को शामिल करने के लिए ऐसा क्यों किया जाएगा? आखिरकार, यह भाषा का एक बदलाव है, VM नहीं: VM का कास्टिंग व्यवहार हमेशा की तरह काम करता है, कंपाइलर इस फीचर को इंटेगर और कॉलिंग .intValue () के लिए मौजूदा तंत्र का उपयोग करके लागू करता है। तो जावा भाषा में यह बदलाव कैसे उचित हो सकता है, वीएम पर अन्य भाषाओं को चलाने में मदद करें? मैं मानता हूं कि आपके लिंक से यह पता चलता है, बस सोच रहा था।
मोर्टी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.