Problema de encoding de Java 8 UTF-8 (¿error de Java?)

Hay una incoherencia al crear una cadena con encoding UTF-8.

Ejecute este código:

public static void encodingIssue() throws IOException { byte[] array = new byte[3]; array[0] = (byte) -19; array[1] = (byte) -69; array[2] = (byte) -100; String str = new String(array, "UTF-8"); for (char c : str.toCharArray()) { System.out.println((int) c); } } 

En Java 1.8.0_20 (y versiones anteriores) tenemos el resultado

 65533 

En Java 1.7 y 1.6 tenemos el resultado correcto:

 57052 

¿Has encontrado este error? ¿Hay una solución para esto?

Esta incoherencia se manifiesta también para Shift_JIS, JIS_X0212-1990, x-IBM300, x-IBM834, x-IBM942, x-IBM942C, x-JIS0208, pero obviamente UTF-8 es el más urgente.

Es una propiedad de la encodingUTF-8 modificada ” para almacenar pares sustitutos (o incluso caracteres desapareados de ese rango) como caracteres individuales. Y es un error si un decodificador que dice usar el UTF-8 estándar usa ” UTF-8 modificado “. Esto parece haber sido arreglado con Java 8.

Puede leer estos datos de manera confiable usando un método que se especifica para usar ” UTF-8 modificado “:

 ByteBuffer bb=ByteBuffer.allocate(array.length+2); bb.putShort((short)array.length).put(array); ByteArrayInputStream bis=new ByteArrayInputStream(bb.array()); DataInputStream dis=new DataInputStream(bis); String str=dis.readUTF(); 

El valor recibido en Java 1.6 / 1.7 es U + DEDC (un sustituto bajo).

De RFC 3629 :

La definición de UTF-8 prohíbe la encoding de números de caracteres entre U + D800 y U + DFFF, que están reservados para su uso con la forma de encoding UTF-16 (como pares de sustitución) y no representan caracteres directamente.

… texto elid …

Las implementaciones del algoritmo de deencoding anterior DEBEN proteger contra la desencoding de secuencias no válidas. Por ejemplo, una implementación ingenua puede decodificar la secuencia U0F-8 demasiado larga C0 80 en el carácter U + 0000, o el par sustituto ED A1 8C ED BE B4 en U + 233B4. La deencoding de secuencias no válidas puede tener consecuencias de seguridad o causar otros problemas.

Java 8 decodifica esto en U + FFFD ( CARÁCTER DE REEMPLAZO ). Parece un error que se solucionó en Java 8.

Eso es un sustituto, ¿verdad? No soy un experto en Unicode, pero no creo que tenga significado en sí mismo. Java 8 cambiado para admitir Unicode 6.2. Quizás es más estricto sobre esto. 65533 es el carácter de reemplazo 0xFFFD estándar, lo que significa “no representable”. ¿Hay algún caso real en el que necesite interpretar esto como una cadena? porque parece que Unicode está diciendo que ya no tiene sentido como personaje.