7

Java言語仕様では、文字列内のエスケープはとのような「通常の」Cである\nと規定されていますが、からへ\tの8進数のエスケープも指定されています。具体的には、JLSは次のように述べています。\0\377

OctalEscape:
    \ OctalDigit
    \ OctalDigit OctalDigit
    \ ZeroToThree OctalDigit OctalDigit

OctalDigit: one of
    0 1 2 3 4 5 6 7

ZeroToThree: one of
    0 1 2 3

\4715これは、Java文字の範囲内にあるにもかかわらず(Java文字はバイトではないため)、のようなものは違法であることを意味します。

なぜJavaにはこの恣意的な制限があるのですか?255を超える文字の8進コードをどのように指定するのですか?

4

4 に答える 4

9

Javaが8進数のエスケープシーケンスをサポートしているのは、おそらく純粋に歴史的な理由によるものです。これらのエスケープシーケンスは、PDP-7のようなコンピューターが地球を支配し、多くのプログラミングがアセンブリまたは直接機械語で行われ、8進数が優先された時代に、C(またはCの前身のBおよびBCPL)で発生しました。命令コードを書くためのベースであり、Unicodeはなく、ASCIIだけだったので、文字セット全体を表すには3つの8進数で十分でした。

UnicodeとJavaが登場する頃には、8進数は、10進数ではうまくいかない場合に、優先される基数として16進数にほとんど取って代わられていました。したがって、Javaに\uは16進数を使用するエスケープシーケンスがあります。8進数のエスケープシーケンスは、Cプログラマーが快適に使用できるようにするため、および文字列定数をCプログラムからJavaプログラムに簡単にコピーして貼り付けるためにサポートされた可能性があります。

歴史的な雑学については、次のリンクを確認してください。

http://en.wikipedia.org/wiki/Octal#In_computers
http://en.wikipedia.org/wiki/PDP-11_architecture#Memory_management

于 2012-03-03T04:59:48.180 に答える
2

ルールを理解できたら(間違っていたら訂正してください):

\ OctalDigit
Examples:
    \0, \1, \2, \3, \4, \5, \6, \7

\ OctalDigit OctalDigit
Examples:
    \00, \07, \17, \27, \37, \47, \57, \67, \77

\ ZeroToThree OctalDigit OctalDigit
Examples:
    \000, \177, \277, \367,\377

\t、、 OctalEscapeルール\n\\該当しない; それらは別々のエスケープ文字ルールの下にある必要があります。

Decimal255はOctal377と同じです(確認するには、科学モードでWindows Calculatorを使用してください)

したがって、3桁の8進数値は\000(0)から\377(255)の範囲になります。

したがって、\4715は3桁を超えるルールであるため、有効な8進数値ではありません。10進値4715のコードポイント文字にアクセスする場合は、すべてのJavaがUnicode UTF-16であるため、Unicodeエスケープ記号\uを使用してUTF-16文字(10進形式の4715)を表します。\u126Bchar

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Character.htmlから:

charデータ型(したがって、Characterオブジェクトがカプセル化する値)は、文字を固定幅の16ビットエンティティとして定義した元のUnicode仕様に基づいています。その後、Unicode標準が変更され、16ビットを超える表現が必要な文字を使用できるようになりました。有効なコードポイントの範囲は、Unicodeスカラー値として知られるU+0000からU+10FFFFになりました。(Unicode標準のU + n表記の定義を参照してください。)

U+0000からU+FFFFまでの文字のセットは、Basic Multilingual Plane(BMP)と呼ばれることもあります。コードポイントがU+FFFFより大きい文字は、補助文字と呼ばれます。Java 2プラットフォームは、char配列、StringクラスおよびStringBufferクラスでUTF-16表現を使用します。この表現では、補足文字はchar値のペアとして表され、最初は高サロゲート範囲(\ uD800- \ uDBFF)から、2番目は低サロゲート範囲(\ uDC00- \ uDFFF)からです。

編集:

8ビット範囲(1バイトより大きい)の有効な8進値を超えるものはすべて、言語固有です。一部のプログラミング言語は、Unicodeの実装に一致するように継続される場合があります。一部はそうではないかもしれません(1バイトに制限してください)。Javaは、Unicodeをサポートしていても、間違いなくそれを許可していません。

1バイトの8進リテラルに制限するいくつかのプログラミング言語(ベンダー依存):

  1. Java(すべてのベンダー):-0から始まる8進数の整数定数、または基数8(0377まで)の1桁。\0から\7、\00から\77、\000から\377(8進文字列リテラル形式)
  2. C / C ++(Microsoft)-0で始まる8進整数定数(0377まで)。8進文字列リテラル形式 \nnn
  3. Ruby-0で始まる8進整数定数(0377まで)。8進文字列リテラル形式\nnn

1バイトを超える8進リテラルをサポートするいくつかのプログラミング言語(ベンダー依存):

  1. Perl-0で始まる8進整数定数。8進文字列リテラル形式http://search.cpan.org/~jesse/perl-5.12.1/pod/perlrebackslash.pod#Octal_escapes\nnnを参照してください

いくつかのプログラミング言語は8進リテラルをサポートしていません

  1. C#-Convert.ToInt32(integer, 8)基数8に使用c#を使用して2進数を8進数に変換するにはどうすればよいですか?
于 2012-03-03T03:30:10.960 に答える
0

\ 0- \ 377の8進数エスケープもCから継承され、文字==バイト(少なくともwchar_tの前のハルシオン日)のCのような言語では、制限はかなり意味があります。

于 2012-03-03T05:00:59.473 に答える
0

8進数のエスケープが0から255のUnicodeコードポイントに制限されている理由はわかりません。これは歴史的な理由による可能性があります。Javaの設計中に8進数のエスケープの範囲を拡大しない技術的な理由がなかったため、この質問は基本的に未回答のままになります。

ただし、Unicodeエスケープと8進数エスケープの間にはそれほど明白な違いはないことに注意してください。8進数のエスケープは文字列の一部としてのみ処理されますが、Unicodeのエスケープは、たとえばクラス名の一部として、ファイル内のどこにでも発生する可能性があります。また、次の例ではコンパイルすらできないことに注意してください。

String a = "\u000A";

その理由は、\ u000Aが非常に早い段階で(基本的にファイルをロードするときに)改行に展開されるためです。次のコードはエラーを生成しません。

String a = "\012";

\ 012は、コンパイラがコードを解析した後に展開されます。これは、\ n、\ r、\tなどの他のエスケープにも当てはまります。

したがって、結論として、Unicodeエスケープは8進数エスケープの代わりにはなりません。それらは完全に異なる概念です。特に、問題を回避するには(上記の\ u000Aの場合のように)、コードポイント0〜255には8進エスケープを使用し、255を超えるコードポイントにはユニコードエスケープを使用する必要があります。

于 2012-09-09T20:48:13.457 に答える