2013-07-28 5 views
25

यदि मैं एक वर्ण को byte में परिवर्तित करता हूं और फिर char पर वापस जाता हूं, तो वह चरित्र रहस्यमय तरीके से गायब हो जाता है और कुछ और बन जाता है। यह कैसे संभव है?जावा में बाइट और चार रूपांतरण

char a = 'È';  // line 1  
byte b = (byte)a; // line 2  
char c = (char)b; // line 3 
System.out.println((char)c + " " + (int)c); 

लाइन तक 2 सब कुछ ठीक है:

इस कोड है

  • लाइन 1 में मैं प्रिंट कर सकता है "एक" कंसोल में है और यह 'ई' में दिखाई देगा।

  • लाइन 2 में मैं कंसोल में "बी" प्रिंट कर सकता हूं और यह दिखाएगा -56, यह 200 है क्योंकि बाइट हस्ताक्षरित है। और 200 "È" है। तो यह अभी भी ठीक है।

लेकिन लाइन 3 में क्या गलत है? "सी" कुछ और बन जाता है और कार्यक्रम ? 65480 प्रिंट करता है। यह कुछ अलग है।

सही परिणाम प्राप्त करने के लिए मुझे लाइन 3 में क्या लिखना चाहिए?

+4

ए 'बाइट'' 8 बिट' है।'char'' 16 बिट' है। विचार मिला? –

+0

char 2byte लेता है। – Ankit

+0

@ रोहितजैन और एक चरित्र - जिसके द्वारा मेरा मतलब यूनिकोड कोड बिंदु है - दो वर्ण या चार बाइट ले सकते हैं। इसके अलावा, कौन जानता है कि सामान्यीकरण के रूप में क्या चीजें हैं? स्ट्रिंग '" È "' में क्रमशः सामान्यीकरण फॉर्म सी या डी में निर्भर करता है या नहीं, इसके आधार पर एक या दो कोड बिंदु शामिल हो सकते हैं। – tchrist

उत्तर

44

जावा में एक वर्ण एक यूनिकोड कोड-इकाई है जिसे एक हस्ताक्षरित संख्या के रूप में माना जाता है। तो अगर आप c = (char)b प्रदर्शन मूल्य आप प्राप्त है 2^16 - 56 या 65536 - 56.

या अधिक सटीक, बाइट पहले मूल्य 0xFFFFFFC8 एक चौड़ा रूपांतरण में संकेत विस्तार उपयोग करने के साथ एक हस्ताक्षरित पूर्णांक में बदल जाती है । इसके बाद बदले में 0xFFC8 तक char पर कास्ट किया जाता है, जो सकारात्मक संख्या 65480 पर अनुवाद करता है।

5.1.4. Widening and Narrowing Primitive Conversion

पहले, बाइट आदिम रूपांतरण को चौड़ा (§5.1.2), और फिर जिसके परिणामस्वरूप पूर्णांक एक में बदल जाती है के माध्यम से एक पूर्णांक में बदल जाती है:

भाषा विनिर्देश से

आदिम रूपांतरण (§5.1.3) को संकुचित करके चार। 0xFFFFFFC80x000000C8 हो जाता है या धनात्मक संख्या 200:


सही बिंदु उपयोग char c = (char) (b & 0xFF) जो पहले एक मुखौटा का उपयोग कर, रूपांतरण के बाद शीर्ष 24 बिट के शून्यीकरण द्वारा सकारात्मक पूर्णांक 200 करने के लिए b की बाइट मूल्य धर्मान्तरित प्राप्त करने के लिए दशमलव में।


ऊपर क्या byte, int और char आदिम प्रकार के बीच रूपांतरण के दौरान होता है का एक सीधा व्याख्या है।

आप, बाइट्स से एन्कोड करने के लिए/डिकोड वर्ण Charset, CharsetEncoder, CharsetDecoder या इस तरह के new String(byte[] bytes, Charset charset) या String#toBytes(Charset charset) के रूप में सुविधा एक विधि का उपयोग करना चाहते हैं। आप StandardCharsets से चरित्र सेट (जैसे यूटीएफ -8 या विंडोज -1252) प्राप्त कर सकते हैं।

+3

असल में, जावा 'char' यूनिकोड * कोड ** बिंदु *** नहीं है। यह एक यूटीएफ -16 * कोड ** इकाई *** है। वास्तव में एक मनमानी यूनिकोड "चरित्र" का प्रतिनिधित्व करने के लिए (जिसके द्वारा मेरा वास्तविक कोड बिंदु है), जावा 'char' पर्याप्त नहीं है: आपको' int' (प्रभावी रूप से आपको यूटीएफ -32 दे रहा है) का उपयोग करना चाहिए, जो उठा सकता है विरासत यूटीएफ -16 नोटेशन में दो वर्णों के लिए। यही कारण है कि सबकुछ में 'कोडपॉइंटएटी' एपीआई है, न केवल बुरी पुरानी विरासत 'charAt' API। – tchrist

+1

@ trrist हाँ, यह थोड़ा बदल गया जब यूनिकोड 64Ki सीमा पार हो गया। –

+0

'char c = (char) (b & 0xFF)' केवल एक बाइट का उपयोग क्यों कर रहा है, जब जावा वर्ण दो बाइट्स होने चाहिए? – statueofmike

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