2008-09-17 9 views
9

आप प्रकार बाइट या कम की चर घोषित हैं और इन पर अंकगणितीय आपरेशनों प्रदर्शन करने के लिए प्रयास करते हैं, तो आपको त्रुटि "प्रकार बेमेल प्राप्त करते हैं: परिवर्तित नहीं कर सकते int से छोटा "(या संगत रूप से" टाइप मिस्चैच: int को बाइट में परिवर्तित नहीं कर सकता ")।जावा: क्यों मैं त्रुटि संदेश "प्रकार बेमेल: बाइट के लिए पूर्णांक परिवर्तित नहीं कर सकते" प्राप्त करते

byte a = 23; 
byte b = 34; 
byte c = a + b;

इस उदाहरण में, संकलन त्रुटि तीसरी पंक्ति पर है।

+1

आईआईआरसी जेवीएम स्टोर बाइट्स और शॉर्ट्स को इनट्स के रूप में स्टोर करता है, इसलिए आमतौर पर इन दो डेटा प्रकारों का उपयोग करने के लिए बहुत कम लाभ होता है। बेशक, मुझे एहसास है कि आप अपने उदाहरण से कहीं अधिक जटिल कर रहे हैं और शायद एक बहुत अच्छा कारण है। –

उत्तर

8

हालांकि अंकगणितीय ऑपरेटरों को जावा भाषा विनिर्देश (5.6.2 बाइनरी न्यूमेरिक प्रमोशन) के अनुसार, किसी भी संख्यात्मक प्रकार पर काम करने के लिए परिभाषित किया गया है, टाइप बाइट के संचालन और ऑपरेटरों को स्वचालित रूप से ऑपरेटर को सौंपने से पहले int को स्वचालित रूप से प्रचारित किया जाता है।

प्रकार बाइट या शॉर्ट के चर पर अंकगणितीय परिचालन करने के लिए, आपको अभिव्यक्ति को कोष्ठक में संलग्न करना होगा (जिसके अंदर ऑपरेशन टाइप int के रूप में किए जाएंगे), और फिर परिणाम को वांछित प्रकार पर डालें।

byte a = 23; 
byte b = 34; 
byte c = (byte) (a + b);

असली जावा गुरुओं पर एक फॉलो-ऑन प्रश्न है: क्यों? प्रकार बाइट और शॉर्ट पूरी तरह से ठीक संख्यात्मक प्रकार हैं। जावा इन प्रकारों पर प्रत्यक्ष अंकगणितीय संचालन की अनुमति क्यों नहीं देता है? (उत्तर "परिशुद्धता का नुकसान" नहीं है, क्योंकि पहले स्थान पर int में कनवर्ट करने का कोई स्पष्ट कारण नहीं है।)

अद्यतन: jrudolph सुझाव देता है कि यह व्यवहार JVM में उपलब्ध संचालन पर आधारित है, विशेष रूप से, कि केवल पूर्ण- और डबल-वर्ड ऑपरेटर लागू किए गए हैं। इसलिए, बाइट्स और शॉर्ट्स पर ऑपरेटर के लिए, उन्हें int में परिवर्तित किया जाना चाहिए।

+0

मुझे लगता है कि प्रदर्शन के कारण है। कुछ सीपीयू में, सीपीयू रजिस्टरों की तुलना में छोटे ऑपरेटरों का उपयोग करना अधिक महंगा हो सकता है। शायद यह स्मृति में गठबंधन रखने के लिए बाइट और शॉर्ट स्टोर करने के लिए 32 बिट int का भी उपयोग करता है। – jassuncao

+0

जब से मैंने पाया - ऑपरेशन सीपीयू रजिस्टरों में किए जाते हैं, लेकिन हाँ वे 32 बिट्स गठबंधन हैं। और आप अक्षर पर + ऑपरेटर को या तो निष्पादित नहीं कर सकते हैं – bestsss

5

अपने अनुवर्ती सवाल का जवाब यहाँ है:

प्रकार बाइट और कम की ऑपरेंड स्वचालित रूप से ऑपरेटरों

तो को सौंप दिए जाने से पहले int करने के लिए प्रोत्साहित कर रहे हैं, अपने उदाहरण में, a और b दोनों + ऑपरेटर को सौंपने से पहले int में परिवर्तित कर दिए गए हैं। दो int एस जोड़ने के नतीजे भी एक int है। फिर int को byte मान को असाइन करने का प्रयास करने से त्रुटि होती है क्योंकि सटीकता का संभावित नुकसान होता है। स्पष्ट रूप से परिणाम कास्टिंग करके आप संकलक को बता रहे हैं "मुझे पता है कि मैं क्या कर रहा हूं"।

2

मुझे लगता है, बात है, कि JVM ढेर मूल्यों के केवल दो प्रकार का समर्थन करता है: शब्द आकार और डबल शब्द आकार।

तब वे शायद फैसला किया है कि वे केवल एक ही आपरेशन कि ढेर पर शब्द आकार पूर्णांकों पर काम करता है की आवश्यकता होगी। तो बाइटकोड स्तर पर केवल iadd, imul और इतने पर है (और बाइट्स और शॉर्ट्स के लिए कोई ऑपरेटर नहीं)।

तो तुम इन आपरेशनों जो जावा सुरक्षित रूप से छोटे बाइट और कम डेटा प्रकार के लिए वापस परिवर्तित नहीं कर सकते का परिणाम के रूप में एक पूर्णांक मूल्य मिलता है। इसलिए वे आपको मूल्य को वापस बाइट/शॉर्ट तक सीमित करने के लिए मजबूर करने के लिए मजबूर करते हैं।

लेकिन अंत में आप ठीक कह रहे हैं: यह व्यवहार, ints के व्यवहार के अनुरूप नहीं है, उदाहरण के लिए। बिना किसी समस्या के आप दो इंट्स जोड़ सकते हैं और परिणाम बहने पर कोई त्रुटि नहीं मिलती है।

1

जावा भाषा हमेशा इंट के लिए लंबे समय तक, नाव या डबल अंकगणितीय ऑपरेटर के तर्कों को बढ़ावा देता है।तो अभिव्यक्ति लें:

a + b 

जहां ए और बी प्रकार बाइट हैं। यह निम्न के लिए लघुरूप है:

(int)a + (int)b 

यह अभिव्यक्ति प्रकार int है। बाइट चर के लिए int मान निर्दिष्ट करते समय यह त्रुटि देने के लिए स्पष्ट रूप से समझ में आता है।

इस तरह से भाषा को परिभाषित क्यों किया जाएगा? मान लीजिए कि 60 था और बी 70 था, फिर ए + बी है -126 - पूर्णांक ओवरफ्लो। एक जटिल जटिल अभिव्यक्ति के हिस्से के रूप में जो एक int में परिणाम होने की उम्मीद थी, यह एक मुश्किल बग हो सकता है। बाइट और शॉर्ट टू सरणी स्टोरेज, फ़ाइल स्वरूप/नेटवर्क प्रोटोकॉल और गूढ़ व्यक्तियों के लिए स्थिरांक का उपयोग प्रतिबंधित करें।

जावापोलिस 2007 से एक दिलचस्प रिकॉर्डिंग है। जेम्स गोस्लिंग एक उदाहरण दे रहा है कि जटिल हस्ताक्षर किए गए अंकगणित (और यह जावा में क्यों नहीं है) के बारे में एक उदाहरण दे रहा है। जोश ब्लोच बताते हैं कि उनका उदाहरण सामान्य हस्ताक्षर अंकगणित के तहत भी गलत उदाहरण देता है। समझने योग्य अंकगणितीय के लिए, हमें मनमाने ढंग से सटीकता की आवश्यकता है।

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