Conversión de bytes y char en Java

Si convierto un carácter en byte y luego vuelvo a char , ese personaje desaparece misteriosamente y se convierte en algo más. ¿Cómo es esto posible?

Este es el código:

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

Hasta la línea 2 todo está bien:

  • En la línea 1 podría imprimir “a” en la consola y mostraría “È”.

  • En la línea 2 podría imprimir “b” en la consola y mostraría -56, eso es 200 porque el byte está firmado. Y 200 es “È”. Entonces todavía está bien.

Pero, ¿qué pasa en la línea 3? “c” se convierte en otra cosa y el progtwig se imprime ? 65480 ? 65480 . Eso es algo completamente diferente.

¿Qué debería escribir en la línea 3 para obtener el resultado correcto?

Un carácter en Java es una unidad de código Unicode que se trata como un número sin signo. Entonces, si realiza c = (char)b el valor que obtiene es 2 ^ 16 – 56 o 65536 – 56.

O más precisamente, el byte primero se convierte en un entero con signo con el valor 0xFFFFFFC8 usando la extensión de signo en una conversión de ampliación. Esto, a su vez, se reduce a 0xFFC8 cuando se 0xFFC8 en un char , lo que se traduce en el número positivo 65480 .

De la especificación del lenguaje:

5.1.4. Ampliación y estrechamiento de la conversión primitiva

En primer lugar, el byte se convierte en un int a través de la conversión de la primitiva de ensanchamiento (§5.1.2), y luego el int resultante se convierte en un char estrechando la conversión primitiva (§5.1.3).


Para obtener el punto correcto use char c = (char) (b & 0xFF) que primero convierte el valor de byte de b en el entero positivo 200 usando una máscara, 0xFFFFFFC8 cero los 24 bits superiores después de la conversión: 0xFFFFFFC8 convierte en 0x000000C8 o el número positivo 200 en decimales


Arriba hay una explicación directa de lo que sucede durante la conversión entre los tipos primitivos byte , int y char .

Si desea codificar / decodificar caracteres desde bytes, use Charset , CharsetEncoder , CharsetDecoder o uno de los métodos de conveniencia, como new String(byte[] bytes, Charset charset) o String#toBytes(Charset charset) . Puede obtener el juego de caracteres (como UTF-8 o Windows-1252) de StandardCharsets .