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 \u202E
cará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 M
se muestra normalmente, pero \u202E
invierte el orden de visualización de todo, desde allí hasta el \u202D
, lo que invierte todo nuevamente. (Formalmente, todo, desde el \u202D
terminador de línea hasta el reverso, se invierte dos veces, una vez debido al \u202D
y 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 .