特定のUnicode文字を使用してコメントでJavaコードを実行できるのはなぜですか?

1366
Reg 2015-06-09 23:02.

次のコードは、「HelloWorld!」という出力を生成します。(実際には、試してみてください)。

public static void main(String... args) {

   // The comment below is not a typo.
   // \u000d System.out.println("Hello World!");
}

これは、JavaコンパイラがUnicode文字\u000dを改行として解析し、次のように変換されるためです。

public static void main(String... args) {

   // The comment below is not a typo.
   //
   System.out.println("Hello World!");
}

したがって、コメントが「実行」されます。

これは、悪意のあるコードや悪意のあるプログラマーが思いつくものを「隠す」ために使用できるのに、なぜコメントで許可されているのでしょうか。

なぜこれがJava仕様で許可されているのですか?

7 answers

747
aioobe 2015-06-09 23:13.

Unicodeデコードは、他の字句翻訳の前に行われます。これの主な利点は、ASCIIと他のエンコーディングの間を行き来するのが簡単になることです。コメントの始まりと終わりを把握する必要はありません。

JLSセクション3.3で述べたように、これにより、ASCIIベースのツールでソースファイルを処理できます。

[...] Javaプログラミング言語は、Unicodeで記述されたプログラムをASCIIに変換する標準的な方法を指定します。これにより、プログラムはASCIIベースのツールで処理できる形式に変更されます。[...]

これにより、Javaプラットフォームの主要な目標であるプラットフォームの独立性(サポートされている文字セットの独立性)が基本的に保証されます。

ファイル内のどこにでもUnicode文字を記述できることは優れた機能であり、ラテン語以外の言語でコードを文書化する場合のコメントでは特に重要です。それがそのような微妙な方法でセマンティクスに干渉する可能性があるという事実は、単なる(不幸な)副作用です。

このテーマとの多くの落とし穴があるのJavaのpuzzlersジョシュア・ブロックとニールGafter氏によっては、以下のバリアントが含まれていました。

これは合法的なJavaプログラムですか?もしそうなら、それは何を印刷しますか?

\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020
\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u006c\u0079
\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020
\u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u0069\u0063
\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028
\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0020
\u0020\u0020\u0020\u0020\u0061\u0072\u0067\u0073\u0029\u007b
\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074
\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020
\u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u0022\u002b
\u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d

(このプログラムは、単純な「HelloWorld」プログラムであることがわかります。)

パズルを解く人の解決策では、彼らは次のことを指摘しています。

さらに深刻なことに、このパズルは、前の3つのレッスンを強化するのに役立ちます。他の方法で表現できない文字をプログラムに挿入する必要がある場合は、Unicodeエスケープが不可欠です。他のすべての場合にはそれらを避けてください。


出典:Java:コメントでコードを実行していますか?!

142
Holger 2015-06-10 07:59.

これはまだ対処されていないので、ここで説明します。Unicodeエスケープの変換が他のソースコード処理の前に行われる理由は次のとおりです。

その背後にある考え方は、異なる文字エンコーディング間でJavaソースコードのロスレス変換を可能にするというものでした。今日、Unicodeが広くサポートされており、これは問題のようには見えませんが、当時、西側諸国の開発者がアジアの同僚からアジアの文字を含むソースコードを受け取り、変更を加えることは容易ではありませんでした(コンパイルとテストを含む)そして結果を送り返すこと、すべて何かを損なうことなく。

そのため、Javaソースコードは任意のエンコーディングで記​​述でき、識別子、文字、Stringリテラル、コメント内でさまざまな文字を使用できます。次に、それをロスレスで転送するために、ターゲットエンコーディングでサポートされていないすべての文字がUnicodeエスケープに置き換えられます。

これは可逆的なプロセスであり、興味深い点は、変換ルールがJavaソースコード構文に依存していないため、Javaソースコード構文について何も知る必要のないツールで変換を実行できることです。これは、コンパイラ内の実際のUnicode文字への変換が、Javaソースコード構文とは独立して行われるため、機能します。これは、ソースコードの意味を変更することなく、双方向で任意の数の変換ステップを実行できることを意味します。

これが、言及されていない別の奇妙な機能の理由です。\uuuuuuxxxx構文:

翻訳ツールが文字をエスケープしていて、すでにエスケープされたシーケンスであるシーケンスに遭遇した場合u、シーケンスに追加を挿入して、に変換する\ucafe必要があり\uucafeます。意味は変わりませんが、他の方向に変換する場合、ツールは1つuを削除し、単一を含むシーケンスのみをuUnicode文字に置き換える必要があります。そうすれば、Unicodeエスケープでさえ、前後に変換するときに元の形式で保持されます。おそらく、誰もその機能を使用したことがないでしょう…

108
Pepijn Schmitz 2015-06-11 07:37.

私は自分自身を助けることができず、まだそれがなされているのを見たことがないという理由だけで、完全に効果のない点を追加するつもりです、それは間違っている隠された前提が含まれているので質問は無効です、すなわちコードはコメント!

Javaソースコードでは、\ u000dはあらゆる点でASCIICR文字と同等です。それは、どこで発生しても、単純で単純な行末です。質問のフォーマットは誤解を招く可能性があります。その文字シーケンスが実際に構文的に対応しているのは次のとおりです。

public static void main(String... args) {
   // The comment below is no typo. 
   // 
 System.out.println("Hello World!");
}

したがって、私見で最も正しい答えは次のとおりです。コメントに含まれていないため、コードが実行されます。次の行にあります。「コメントでコードを実行する」ことは、あなたが期待するように、Javaでは許可されていません。

混乱の多くは、構文ハイライターとIDEがこの状況を考慮に入れるほど洗練されていないという事実から生じています。Unicodeエスケープをまったく処理しないか、コードを解析する前ではなく解析した後に処理しますjavac

69
zwol 2015-06-10 05:16.

\u000dので、エスケープがコメントを終了\uエスケープは一様に対応するUnicode文字に変換されます前に、プログラムがトークン化されます。コメントを開始する\u0057\u0057代わりに、同様に使用できます。//

これはIDEのバグであり、構文を強調表示して\u000d、コメントの終わりを明確にする必要があります。

これは、言語の設計エラーでもあります。それに依存するプログラムを壊してしまうので、今は修正できません。 \uエスケープは、コンパイラが「意味のある」コンテキスト(文字列リテラルと識別子、おそらく他の場所ではない)でのみ、対応するUnicode文字に変換するか、U + 0000〜007Fの範囲の文字を生成することを禁止する必要があります。 、 または両方。これらのセマンティクスのいずれかにより、\u000dエスケープ\uが役立つ場合を妨げることなく、コメントがエスケープによって終了するのを防ぐことができます。これには、非ラテン文字でコメントをエンコードする方法としてコメント内でエスケープを使用することが含まれることに注意してください。\uテキストエディタは\u、コンパイラよりもエスケープが重要な場所をより広い視野で捉えることができます。(ただし\uどのコンテキストでも、対応する文字としてエスケープを表示するエディターまたはIDEはありません。)

Cの家族の中で同様の設計誤りがあり、1バックスラッシュ-改行コメントの境界前に処理されるなどして、決定されています

// this is a comment \
   this is still in the comment!

これを取り上げて、この特定の設計エラーを簡単に作成できることを説明します。トークン化について考え、コンパイラプログラマーの考え方を解析することに慣れている場合は、修正するには手遅れになるまでエラーであることに気づきません。トークン化と解析について。基本的に、正式な文法をすでに定義していて、誰かが構文上の特殊なケース(trigraphs、backslash-newline、ASCIIに制限されたソースファイル内の任意のUnicode文字のエンコードなど)を思いついた場合は、それを組み込む必要があります。トークナイザーを再定義して、その特殊なケースを使用する意味がある場所に注意を払うよりも、トークナイザーの前に変換パスを追加します。

1衒学者の場合:Cのこの側面は100%意図的なものであり、パンチカードに任意の長さの行を含むコードを機械的に強制的に適合させることができるという理論的根拠(私はこれを構成していません)を認識しています。それはまだ間違った設計上の決定でした。

22
Jonathan Gibbons 2015-06-10 08:45.

これは、Javaの元の設計にまでさかのぼる意図的な設計の選択でした。

「コメントでUnicodeエスケープが必要なのは誰か」と尋ねる人々にとって、彼らは母国語がラテン文字セットを使用している人々だと思います。言い換えれば、Javaプログラムの合法的な場所、最も一般的にはコメントや文字列で、人々が任意のUnicode文字を使用できることはJavaの元の設計に固有のものです。

ソーステキストを表示するために使用されるプログラム(IDEなど)の欠点は、そのようなプログラムがUnicodeエスケープを解釈して、対応するグリフを表示できないことです。

21
ZhongYu 2015-06-10 06:47.

これは設計上の間違いであるという@zwolに同意します。しかし、私はそれに対してさらに批判的です。

\uエスケープは、文字列および文字リテラルで役立ちます。そしてそれが存在すべき唯一の場所です。\n;のような他のエスケープと同じ方法で処理する必要があります。そして、"\u000A" すべきである正確に意味"\n"

\uxxxxコメントに入れる意味はまったくありません-誰もそれを読むことができません。

同様\uxxxxに、プログラムの他の部分で使用する意味はありません。唯一の例外は、おそらくいくつかの非ASCII文字を含むように強制されたパブリックAPIにあります-それを最後に見たのは何ですか?

設計者には1995年に理由がありましたが、20年後、これは間違った選択のようです。

(読者への質問-なぜこの質問は新しい票を獲得し続けるのですか?この質問はどこか人気のある場所からリンクされていますか?)

11
Martijn 2015-06-13 01:59.

Unicodeエスケープがそのまま実装された理由に答えられるのは、仕様を書いた人だけです。

これのもっともらしい理由は、Javaソースコードの可能な文字としてBMP全体を許可したいという願望があったことです。ただし、これには問題があります。

  • 任意のBMP文字を使用できるようにする必要があります。
  • 適度に簡単にBMP文字を入力できるようにする必要があります。これを行う方法は、Unicodeエスケープを使用することです。
  • 字句仕様を人間が読み書きしやすく、実装も合理的に簡単に保つ必要があります。

Unicodeエスケープが争いに入ると、これは非常に困難です。新しいレクサールールが大量に作成されます。

簡単な方法は、2つのステップで字句解析を行うことです。最初にすべてのUnicodeエスケープを検索してそれが表す文字に置き換え、次に結果のドキュメントをUnicodeエスケープが存在しないかのように解析します。

これの利点は、指定が簡単であるため、指定が簡単になり、実装が簡単になることです。

欠点は、まあ、あなたの例です。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

2021 年 6 月 8 日にニューヨーク市で開催された covid-19 パンデミックで亡くなった人々の命を偲び、祝うために、ネーミング ザ ロスト メモリアルズが主催するイベントと行進の最中に、グリーンウッド墓地の正門から記念碑がぶら下がっています。週末、ジョー・バイデン大統領は、covid-19 パンデミックの終息を宣言しました。これは、過去 2 年以上にわたり、公の場でそうするための長い列の中で最新のものです。

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

オハイオ州のエミリー・デシャネル みんな早く来て、ボーンズが帰ってきた!まあ、ショーボーンズではなく、彼女を演じた俳優. エミリー・デシャネルに最後に会ってからしばらく経ちました.Emily Deschanel は、長期にわたるプロシージャルな Bones の Temperance “Bones” Brennan としてよく知られています。

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

どうやら、ドナルド・トランプに近い人々は、今月初めにFBIによって家宅捜索された彼のMar-a-Lago財産からの映像を公開するよう彼に勧めています. 前大統領はテープを公開するかどうかを確認していませんが、息子はフォックス・ニュースにそうなるだろうと語った.

Andor は、他の Star Wars ショーから大きな距離を置きます。

Andor は、他の Star Wars ショーから大きな距離を置きます。

アンドールの一場面。数十年前、ジョージ・ルーカスがスター・ウォーズのテレビ番組を制作するのを妨げた主な理由は、お金でした。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language