Existem caracteres invisíveis aqui que alteram a forma como o código é exibido. No Intellij, eles podem ser encontrados copiando e colando o código em uma string vazia ( ""
), que os substitui por escapes Unicode, removendo seus efeitos e revelando a ordem que o compilador vê.
Aqui está a saída dessa copiar e colar:
"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','!'});}} "
Os caracteres do código-fonte são armazenados nesta ordem e o compilador os trata como estando nessa ordem, mas são exibidos de maneira diferente.
Observe o \u202E
caractere, que é uma substituição da direita para a esquerda, iniciando um bloco em que todos os caracteres são forçados a serem exibidos da direita para a esquerda e o \u202D
, que é uma substituição da esquerda para a direita, iniciando um bloco aninhado onde todos os caracteres são forçados na ordem da esquerda para a direita, substituindo a primeira substituição.
Logo, quando ele exibe o código original, class M
é exibido normalmente, mas \u202E
inverte a ordem de exibição de tudo, de lá para o \u202D
, o que reverte tudo novamente. (Formalmente, tudo, desde o terminal \u202D
até a linha, é revertido duas vezes, uma vez devido ao \u202D
e uma vez com o restante do texto revertido devido ao \u202E
, motivo pelo qual esse texto aparece no meio da linha e não no final.) A direcionalidade da próxima linha é tratada independentemente da primeira devido ao terminador da linha, {'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
sendo exibida normalmente.
Para o algoritmo bidirecional Unicode completo (extremamente complexo, com dezenas de páginas), consulte o Anexo # 9 do Padrão Unicode .