2013-04-20 17 views
106

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

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

यह जावा SE 7 से javac के साथ ठीक संकलित हालांकि, अगर मैं संकलक "स्रोत 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 के बीच, unboxing सुविधा इतना है कि यह Unbox वस्तु प्रकार डाली और एक बार में कर सकता है बढ़ाया गया था, (संकलन समय पर) कि मूल्य उचित बॉक्स प्रकार का है। हालांकि, जावा भाषा विशिष्टता या ब्लॉग पोस्टिंग के माध्यम से पढ़ना जो जावा 7 के समय लिखा गया था, मुझे इस बात का कोई बदलाव नहीं दिख रहा है, इसलिए मैं सोच रहा हूं कि परिवर्तन क्या है और यह "फीचर" कहलाता है ?

बस एक जिज्ञासा:

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

यह ठीक संकलित लेकिन क्रम में एक ClassCastException देता है: परिवर्तन कारण, यह "गलत" unboxings को गति प्रदान करने के लिए संभव है।

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

+17

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

+1

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

+1

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

उत्तर

91

यह भाषा section 5.5 Casting Conversion of Java 7 JLS में the same section in the Java 5/6 JLS की तुलना में अद्यतन किया गया था की तरह लग रहा है, शायद अनुमति रूपांतरण स्पष्ट करने के लिए।

जावा 7 JLS कहते

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

जावा 5/6:

एक संदर्भ प्रकार का मान unboxing रूपांतरण द्वारा एक आदिम प्रकार के लिए डाली जा सकती है (§5.1.8)।

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

कारण this email में समझाया गया है:

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

+10

+1 धड़कता है। –

35

आप सही हैं; अधिक बस इसे डाल करने के लिए:

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

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

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

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

संकलन है, लेकिन क्रम में (ClassCastException के साथ) असफल हो जायेगी। यह, बजाय, काम करेंगे:

long x = (long)(int)obj;

+2

उत्तर के लिए धन्यवाद। हालांकि, एक बात है जिसे मैं समझ नहीं पा रहा हूं। यह जेएलएस और साथ में कार्यान्वयन (सीएफ। मेल चर्चा) का एक स्पष्टीकरण है, लेकिन यह JVM पर अन्य टाइप की गई भाषाओं को समायोजित करने के लिए क्यों किया जाएगा? आखिरकार, यह भाषा में बदलाव है, वीएम नहीं: वीएम का कास्टिंग व्यवहार हमेशा के रूप में काम करता है, संकलक इंटीजर को कास्टिंग और कॉलिंग के लिए मौजूदा तंत्र का उपयोग करके इस सुविधा को लागू करता है .intValue()। तो जावा भाषा में यह परिवर्तन कैसे उचित हो सकता है, वीएम पर अन्य भाषाओं को चलाने में मदद करें? मैं सहमत हूं कि आपका लिंक यह सुझाव देता है, बस सोच रहा है। – Morty

+2

@ मॉर्टी: इस के मूल (जेएलएस) पर जाने के लिए मुझे – leonbloy

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