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 \u202Ecaractè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 Ms'affiche normalement, mais l' \u202Einverse l'ordre d'affichage de tout de là vers le \u202D, qui inverse à nouveau tout. (Formellement, tout depuis le \u202Dterminateur de ligne est inversé deux fois, une fois en raison de la \u202Det 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 .