Aquí hay caracteres invisibles que alteran la forma en que se muestra el código. En Intellij, estos se pueden encontrar copiando y pegando el código en una cadena vacía ( ""), que los reemplaza con escapes Unicode, eliminando sus efectos y revelando el orden que ve el compilador.
Aquí está la salida de ese copiar y pegar:
"class M\u202E{public static void main(String[]a\u202D){System.out.print(new char[]\n"+
"{'H','e','l','l','o',' ','W','o','r','l','d','!'});}} "
Los caracteres del código fuente se almacenan en este orden, y el compilador los trata como si estuvieran en este orden, pero se muestran de manera diferente.
Tenga en cuenta que el \u202Ecarácter, que es una anulación de derecha a izquierda, comienza un bloque donde todos los caracteres están obligados a mostrarse de derecha a izquierda, y el \u202D, que es una anulación de izquierda a derecha, inicia un bloque anidado donde todos los caracteres se fuerzan en orden de izquierda a derecha, anulando la primera anulación.
Ergo, cuando muestra el código original, class Mse muestra normalmente, pero \u202Einvierte el orden de visualización de todo, desde allí hasta el \u202D, lo que invierte todo nuevamente. (Formalmente, todo, desde el \u202Dterminador de línea hasta el reverso, se invierte dos veces, una vez debido al \u202Dy el resto del texto invertido debido a la \u202E, por lo que este texto aparece en el medio de la línea en lugar del final). La direccionalidad de la línea siguiente se maneja independientemente de la primera debido al terminador de línea, por lo que {'H','e','l','l','o',' ','W','o','r','l','d','!'});}}se muestra normalmente.
Para el algoritmo bidireccional Unicode completo (extremadamente complejo, decenas de páginas de largo), consulte el Anexo 9 estándar de Unicode .