array - byte[] to char[] java
Conversión de bytes y char en Java (1)
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 programa 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
.