57

私は今日これを(再び)つまずいた:

class Test {
    char ok = '\n';
    char okAsWell = '\u000B';
    char error = '\u000A';
}

コンパイルされません:

4 行目の文字定数が無効です。

コンパイラは、代わりに '\n' を書くように要求しているようです。これには理由がありませんが、非常に迷惑です。

\t特別な表記法 ( 、\n、 など\r)を持つ文字をJava ソースでその形式で表現しなければならない理由の論理的な説明はありますか?

4

5 に答える 5

85

Unicode 文字はその値に置き換えられるため、行はコンパイラによって次のように置き換えられます。

char error = '
';

これは有効な Java ステートメントではありません。

これは、言語仕様によって規定されています。

Java プログラミング言語のコンパイラ (「Java コンパイラ」) は、最初に入力内の Unicode エスケープを認識し、ASCII 文字 \u とそれに続く 4 桁の 16 進数を、指定された 16 進数値の UTF-16 コード単位 (§3.1) に変換します。他のすべての文字を変更せずに渡します。補助文字を表すには、2 つの連続した Unicode エスケープが必要です。この変換ステップにより、一連の Unicode 入力文字が生成されます。

これは驚くべきことにつながる可能性があります。たとえば、これは有効な Java プログラムです (非表示の Unicode 文字が含まれています) - Peter Lawrey の厚意により:

public static void main(String[] args) {
    for (char c‮h = 0; c‮h < Character.MAX_VALUE; c‮h++) {
        if (Character.isJavaIdentifierPart(c‮h) && !Character.isJavaIdentifierStart(c‮h)) {
            System.out.printf("%04x <%s>%n", (int) c‮h, "" + c‮h);
        }
    }
}
于 2013-03-07T16:12:44.280 に答える
23

のような Unicode エスケープ シーケンス\u000aは、Java コンパイラがソース コードに対して他の処理を行う前に、それらが表す実際の文字に置き換えられます。したがって、プログラムは最終的に

char ch = '
';

したがって、\u000aソース コード内の は、内部的に改行文字に置き換えられます。これは、コンパイラが実際にソース コードを読み取って解釈する前に発生することに注意してください。

Java 言語仕様を参照する:

行末記号 (§3.4) が開始 ' の後、終了' の前に現れるのは、コンパイル時エラーです。

そして、誰もが心に留めて\nいるのは、次の引用による行ターミネーターです。

 LineTerminator:
    the ASCII LF character, also known as "newline"
    the ASCII CR character, also known as "return"
    the ASCII CR character followed by the ASCII LF character

問題を引き起こす可能性のあるその他の記号は\、 、'および"です。

于 2013-03-07T16:13:33.423 に答える
4

\uXXXXその理由は、コードが解析されているときにシーケンスが展開されるためだと思います。JLS §3.2 を参照してください。語彙翻訳

于 2013-03-07T16:14:12.497 に答える
4

3.3 で説明します。Unicode エスケープhttp://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html。Javac は最初に .java 内の \uxxxx シーケンスを検出し、それらを実際の文字に置き換えてからコンパイルします。の場合には

char error = '\u000A';

\u000A はnewline文字コード (10) に置き換えられ、実際のテキストは

char error = '
';
于 2013-03-07T16:23:14.623 に答える
2

コンパイラはそれらをエスケープされていないテキストと同じように扱うためです。

これは有効なコードです:

 class \u00C9 {}
于 2013-03-07T16:13:40.330 に答える