2013-07-28 5 views
25

문자를 byte으로 변환 한 다음 char으로 다시 변환하면 해당 문자가 신비하게 사라져서 다른 것으로 변합니다. 이것이 어떻게 가능한지? 이 모든 것이 괜찮Java에서 바이트 및 문자 변환

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

라인까지 :

코드입니다

  • 라인 1에서 나는 "A"콘솔에 인쇄 할 수 있으며 "E"가 표시됩니다.

  • 2 행에서 "b"를 콘솔에 인쇄 할 수 있으며 -56, 즉 바이트가 서명되어 있기 때문에 200이 표시됩니다. 그리고 200은 "È"입니다. 그래도 괜찮습니다.

3 번 줄에는 무엇이 잘못 되었습니까? "c"는 다른 것이되고 프로그램은 ? 65480을 인쇄합니다. 그것은 완전히 다른 것입니다.

올바른 결과를 얻으려면 3 행에 무엇을 써야합니까?

+4

'바이트'는 '8 비트'입니다.'char'는'16 비트'입니다. 아이디어 있니? –

+0

char가 2 바이트를 차지합니다. – Ankit

+0

@RohitJain 그리고 유니 코드 코드 포인트를 의미하는 문자는 2 개의 문자 또는 4 바이트를 취할 수 있습니다. 게다가, 어떤 정규화 형태가 존재하는지 누가 알 수 있습니까? 문자열 ""은 자체가 정규화 형식 C인지 D인지에 따라 각각 하나 또는 두 개의 코드 포인트로 구성 될 수 있습니다. – tchrist

답변

44

Java의 문자는 부호없는 숫자로 취급되는 유니 코드 코드 단위입니다. 당신이 c = (char)b을 수행한다면 당신이 얻을 값은 2^16-56 또는 65536 - 56

또는 더 정확하게 먼저 확대 변환에 ​​부호 확장를 사용하여 값 0xFFFFFFC8와 부호있는 정수로 변환되는 바이트 . 이 값은 char으로 변환 할 때 0xFFC8으로 좁혀지고 양수는 65480입니다.

5.1.4. Widening and Narrowing Primitive Conversion

우선, 바이트 (§5.1.2) 후 얻어진 INT가 변환되는 기본 변환 넓어 통해 int로 변환된다 : 언어 규격에서

char 기본 변환을 좁혀서 (§5.1.3). 0xFFFFFFC80x000000C8된다 또는 양수 200 :


먼저 변환 후의 상부 24 비트를 제로화 마스크를 이용하여 양의 정수 200- b의 바이트 값을 변환 오른쪽 점 사용 char c = (char) (b & 0xFF)을 얻으려면 십진수로.


위의 byte, intchar 기본 유형 간의 변환시에 어떤 일이 발생하는지에 대해 직접 설명이다.

당신이 바이트에서/디코드 문자를 인코딩 Charset, CharsetEncoder, CharsetDecoder 또는 new String(byte[] bytes, Charset charset) 또는 String#toBytes(Charset charset) 같은 편의 방법 중 하나를 사용하십시오. StandardCharsets에서 문자 세트 (예 : UTF-8 또는 Windows-1252)를 가져올 수 있습니다.

+3

사실, 자바'char'는 유니 코드 * 코드 ** 포인트가 아닙니다 ***. UTF-16 * 코드 ** 단위 ***입니다. 실제로 임의의 유니 코드 "문자"(실제 코드 포인트를 의미 함)를 표현하기 위해 자바'char'만으로는 충분하지 않습니다.'int' (효과적으로 UTF-32를 제공)를 사용해야합니다. 레거시 UTF-16 표기법의 두 문자 그래서 모든 것이'codePointAt' API를 가지고 있는데, 이는 오래된 오래된'charAt' API 뿐만이 아닙니다. – tchrist

+1

@tchrist 네, 유니 코드가 64Ki 경계를 넘었을 때 약간 바뀌 었습니다. –

+0

Java chars가 2 바이트라고 가정 할 때'char c = (char) (b & 0xFF)'는 1 바이트 만 사용하는 이유는 무엇입니까? – statueofmike

관련 문제