Są tu niewidoczne znaki, które zmieniają sposób wyświetlania kodu. W Intellij można je znaleźć, wklejając kod do pustego łańcucha (""
), który zastępuje je znakami ucieczki Unicode, usuwając ich efekty i ujawniając kolejność, jaką widzi kompilator.
Oto wynik tej kopiuj-wklej:
"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','!'});}} "
Znaki kodu źródłowego są przechowywane w tej kolejności, a kompilator traktuje je jako znajdujące się w tej kolejności, ale są wyświetlane inaczej.
Zwróć uwagę na \u202E
znak, który jest przesłonięciem od prawej do lewej, rozpoczynając blok, w którym wszystkie znaki muszą być wyświetlane od prawej do lewej, oraz\u202D
lewej do prawej, rozpoczynając zagnieżdżony blok, w którym wszystkie znaki są wymuszane w kolejności od lewej do prawej, zastępując pierwszą zmianę.
Ergo, gdy wyświetla oryginalny kod, class M
jest wyświetlane normalnie, ale \u202E
odwraca kolejność wyświetlania wszystkiego od tego do \u202D
, co odwraca wszystko ponownie. (Formalnie wszystko od \u202D
terminatora do wiersza jest dwukrotnie odwracane, raz z powodu \u202D
i raz z resztą tekstu odwróconego z powodu \u202E
, i dlatego ten tekst pojawia się na środku linii zamiast na końcu.) Kierunkowość następnej linii jest obsługiwana niezależnie od pierwszej z powodu zakończenia linii, więc {'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
jest wyświetlana normalnie.
Aby zapoznać się z pełnym (niezwykle złożonym, dziesiątkami stron) algorytmem dwukierunkowym Unicode, zobacz Standardowy kod Unicode, załącznik nr 9 .