3

私は次のコードに出くわしました:

public class LinePrinter {
    public static void main(String args[]) {
      //Note: \u000A is unicode for Line Feed
      char c=0x000A;
      System.out.println(c);
    }
}

Unicodeの置き換えが行われたため、これはコンパイルされません。

問題は、コメント//)がコンパイラによって行われるUnicode置換をオーバーライドしないのはなぜですか?コード変換で他のことをする前に、コンパイラは最初にコメントを無視するべきだと思いました。

編集:

上記が十分に明確であるかどうかわからない。

上記で何が起こり、なぜエラーになるのかを知っています。私の期待は、コンパイラがコードで変換を行う前に、コメントされたすべての行を無視する必要があることです。明らかに、ここではそうではありません。私はこの振る舞いの論理的根拠を期待しています。

4

2 に答える 2

5

これはJavaPuzzlers#14にあります-説明の抜粋:

このパズルを理解するための鍵は、Javaが文字列リテラル内のUnicodeエスケープに対して特別な処理を提供しないことです。コンパイラは、プログラムを文字列リテラル[JLS 3.2]などのトークンに解析する前に、Unicodeエスケープをそれらが表す文字に変換します。

JLS v7の関連する段落は、3.3項です。

Javaプログラミング言語用のコンパイラ(「Javaコンパイラ」)は、最初に入力でUnicodeエスケープを認識し、ASCII文字\ uの後に4桁の16進数を、指定された16進値のUTF-16コードユニット(§3.1)に変換します。他のすべての文字を変更せずに渡します。

JLSのセクション3の概要は、これが当てはまる理由についてのヒントを提供します。

プログラムはUnicode(§3.1)で記述されていますが、Unicodeエスケープ(§3.3)を使用してASCII文字のみを使用する任意のUnicode文字を含めることができるように、字句翻訳が提供されています(§3.2)。

于 2012-12-07T11:09:05.233 に答える
2

native2ascii仕様では、Javaコンパイラは、他の処理を行う前にUnicodeエスケープを対応する文字に変換する必要があると規定されています。これにより、コードが保存または送信されないチャネルを介してコードが保存または送信されるときに、識別子の非ASCII文字などを保護できます。 8ビットクリーン。

このルールはグローバルに適用されます。特に、Unicodeエスケープを使用してコメントマーカーをエスケープすることもできます。たとえば、次の2つのスニペットは同一です。

// Deal with opening and closing comment characters /*, etc.
myRisquéParser.handle("/*", "*/");

\u002F\u002F Deal with opening and closing comment characters /*, etc.
myRisqu\u00E9Parser.handle("/*", "*/");

コンパイラがUnicodeエスケープを処理する前にコメントを削除しようとすると、からまでのすべてが削除さ/*, etc.handle("/*", "*/

\u002F\u002F Deal with opening and closing comment characters ");

その後、1行のコメントにエスケープ解除され、解析の次の段階で削除されます。したがって、コンパイラエラーや警告は生成されませんが、コードの行全体がサイレントにドロップされます...

于 2012-12-07T11:35:40.017 に答える