1. ホーム

[解決済み】このコードを逆から書くと、なぜ "Hello World!"と表示されるのか?

2022-05-05 03:51:12

質問

以下は、インターネットで見つけたコードです。

class M‮{public static void main(String[]a‭){System.out.print(new char[]
{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}    

このコードでは Hello World! を実行すると、画面に表示されます。 ここで . はっきりわかるのは public static void main と書かれていますが、逆になっています。このコードはどのように動作するのでしょうか?こんなのどうやってコンパイルするんだ?

編集してください。 このコードをIntellIJで試したところ、問題なく動作しました。しかし、なぜかnotepad++ではcmdと一緒に動作しません。その解決策はまだ見つかっていないので、もし知っている人がいたら、下にコメントしてください。

解決方法は?

ここには、コードの表示方法を変更する不可視文字があります。Intellijでは、コードを空の文字列にコピー・ペーストすることで見つけることができます ( "" に置き換えると、Unicode エスケープに置き換えられ、それらの効果がなくなり、コンパイラが見る順番が明らかになります。

そのコピーペーストの出力がこちら。

"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','!'});}}   "

ソースコードの文字はこの順番で格納されており、コンパイラもこの順番で扱いますが、表示は異なります。

なお \u202E 文字は右から左へのオーバーライドで、すべての文字が右から左に表示されるように強制されるブロックを開始します。 \u202D これは左から右へのオーバーライドで、ネストされたブロックが始まり、最初のオーバーライドを上書きしてすべての文字が左から右の順序になるように強制されます。

つまり、元のコードを表示したとき。 class M は正常に表示されますが \u202E は、そこから先のすべての表示順を逆転させ、さらに \u202D で、これがまたすべてを反転させる。(形式的には \u202D によって行末が2回反転されます。 \u202D により、残りのテキストが反転しています。 \u202E そのため、このテキストは行の最後ではなく、途中に表示されます)。次の行の方向性は、行の終端記号によって最初の行とは独立して処理されます。 {'H','e','l','l','o',' ','W','o','r','l','d','!'});}} は正常に表示されます。

完全な(非常に複雑で何十ページにもわたる)Unicode双方向性アルゴリズムについては ユニコード標準付属書第9号 .