Il y a des caractères invisibles ici qui modifient la façon dont le code est affiché. Dans Intellij ceux-ci peuvent être trouvés en copiant-collant le code dans une chaîne vide ( ""
), qui les remplace par des échappements Unicode, supprimant leurs effets et révélant l'ordre que le compilateur voit.
Voici la sortie de ce copier-coller:
"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','!'});}} "
Les caractères du code source sont stockés dans cet ordre et le compilateur les traite comme étant dans cet ordre, mais ils s'affichent différemment.
Notez le \u202E
caractère, qui est un remplacement de droite à gauche, en commençant un bloc où tous les caractères sont forcés d'être affichés de droite à gauche, et le \u202D
, qui est un remplacement de gauche à droite, en commençant un bloc imbriqué où tous les caractères sont forcés dans un ordre de gauche à droite, remplaçant le premier remplacement.
Ergo, lorsqu'il affiche le code d'origine, class M
s'affiche normalement, mais l' \u202E
inverse l'ordre d'affichage de tout de là vers le \u202D
, qui inverse à nouveau tout. (Formellement, tout depuis le \u202D
terminateur de ligne est inversé deux fois, une fois en raison de la \u202D
et une fois avec le reste du texte inversé en raison de la \u202E
, c'est pourquoi ce texte apparaît au milieu de la ligne au lieu de la fin.) La directionnalité de la ligne suivante est gérée indépendamment de la première en raison du terminateur de ligne, elle {'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
est donc affichée normalement.
Pour l'algorithme bidirectionnel Unicode complet (extrêmement complexe, des dizaines de pages de long), voir l' Annexe # 9 de la norme Unicode .